OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inet6vpn_table.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include "bgp/ipeer.h"
8 #include "bgp/bgp_server.h"
9 #include "bgp/bgp_peer.h"
10 #include "bgp/bgp_update.h"
11 #include "bgp/inet6/inet6_table.h"
13 #include "net/rd.h"
14 
15 Inet6VpnTable::Inet6VpnTable(DB *db, const std::string &name)
16  : BgpTable(db, name) {
17 }
18 
19 std::unique_ptr<DBEntry>
21  const RequestKey *pfxkey = static_cast<const RequestKey *>(key);
22  return std::unique_ptr<DBEntry>(new Inet6VpnRoute(pfxkey->prefix));
23 }
24 
25 std::unique_ptr<DBEntry>
26 Inet6VpnTable::AllocEntryStr(const std::string &key_str) const {
27  Inet6VpnPrefix vpn_prefix = Inet6VpnPrefix::FromString(key_str);
28  return std::unique_ptr<DBEntry> (new Inet6VpnRoute(vpn_prefix));
29 }
30 
31 size_t Inet6VpnTable::Hash(const DBEntry *entry) const {
32  const Inet6VpnRoute *vpn_route = static_cast<const Inet6VpnRoute *>(entry);
33  const Inet6VpnPrefix &vpn_prefix = vpn_route->GetPrefix();
34  Inet6Prefix prefix(vpn_prefix.addr(), vpn_prefix.prefixlen());
35  size_t value = Inet6Table::HashFunction(prefix);
36  return value % DB::PartitionCount();
37 }
38 
39 size_t Inet6VpnTable::Hash(const DBRequestKey *key) const {
40  const RequestKey *rkey = static_cast<const RequestKey *>(key);
41  Inet6Prefix prefix(rkey->prefix.addr(), rkey->prefix.prefixlen());
42  size_t value = Inet6Table::HashFunction(prefix);
43  return value % DB::PartitionCount();
44 }
45 
47  const DBRequestKey *prefix) {
48  const RequestKey *pfxkey = static_cast<const RequestKey *>(prefix);
49  Inet6VpnRoute vpn_route(pfxkey->prefix);
50  return static_cast<BgpRoute *>(rtp->Find(&vpn_route));
51 }
52 
53 DBTableBase *Inet6VpnTable::CreateTable(DB *db, const std::string &name) {
54  Inet6VpnTable *table = new Inet6VpnTable(db, name);
55  table->Init();
56  return table;
57 }
58 
60  const BgpTable *src_table, const BgpPath *src_path) {
61  const RouteDistinguisher &source_rd = src_path->GetAttr()->source_rd();
62  if (!src_path->GetPeer() || !(src_path->GetPeer()->IsRouterTypeBGPaaS())){
63  if (!source_rd.IsZero())
64  return source_rd;
65 
66  assert(!src_path->GetPeer() || !src_path->GetPeer()->IsXmppPeer());
67  const RoutingInstance *src_instance = src_table->routing_instance();
68  return *src_instance->GetRD();
69  }
70  uint16_t peer_port_id = 0;
71  as_t asn_num = src_path->GetAttr()->neighbor_as();
72 
73  std::string ri_name = src_table->routing_instance()->name();
74  for (const BgpPeer *peer = src_path->GetPeer()->server()->FindNextPeer(); peer != NULL;
75  peer = src_path->GetPeer()->server()->FindNextPeer(peer->peer_name())) {
76  if ((peer->peer_name().find(ri_name)!= std::string::npos)&&
77  (peer->peer_address_string().find(src_path->GetPeer()->ToString())!= std::string::npos)){
78  peer_port_id = peer->peer_port();
79  asn_num = peer->peer_as();
80  break;
81  }
82  }
83  RouteDistinguisher new_source_rd = RouteDistinguisher(true, asn_num, peer_port_id);
84  return new_source_rd;
85 }
86 
88  BgpRoute *source_rt, const BgpPath *src_path,
89  ExtCommunityPtr community) {
90  assert(src_table->family() == Address::INET6);
91 
92  Inet6Route *src_rt = dynamic_cast<Inet6Route *>(source_rt);
93  assert(src_rt);
94 
95  const RouteDistinguisher &rd = GenerateDistinguisher(src_table, src_path);
96  Inet6VpnPrefix vpn_prefix(rd, src_rt->GetPrefix().ip6_addr(),
97  src_rt->GetPrefix().prefixlen());
98 
99  Inet6VpnRoute vpn_route(vpn_prefix);
100  DBTablePartition *partition =
101  static_cast<DBTablePartition *>(GetTablePartition(&vpn_route));
102  BgpRoute *dest_route = static_cast<BgpRoute *>(partition->Find(&vpn_route));
103  if (dest_route == NULL) {
104  dest_route = new Inet6VpnRoute(vpn_prefix);
105  partition->Add(dest_route);
106  } else {
107  dest_route->ClearDelete();
108  }
109 
110  BgpAttrDB *attr_db = server->attr_db();
111 
112  BgpAttrPtr new_attr =
113  server->attr_db()->ReplaceExtCommunityAndLocate(src_path->GetAttr(),
114  community);
115  new_attr = attr_db->ReplaceSourceRdAndLocate(new_attr.get(), rd);
116 
117  // Check whether there's already a path with the given peer and path id.
118  BgpPath *dest_path =
119  dest_route->FindSecondaryPath(source_rt, src_path->GetSource(),
120  src_path->GetPeer(),
121  src_path->GetPathId());
122  if (dest_path != NULL) {
123  if ((new_attr != dest_path->GetOriginalAttr()) ||
124  (src_path->GetFlags() != dest_path->GetFlags()) ||
125  (src_path->GetLabel() != dest_path->GetLabel())) {
126  // Update Attributes and notify (if needed)
127  assert(dest_route->RemoveSecondaryPath(source_rt,
128  src_path->GetSource(), src_path->GetPeer(),
129  src_path->GetPathId()));
130  } else {
131  return dest_route;
132  }
133  }
134 
135  // Create replicated path and insert it on the route
136  BgpSecondaryPath *replicated_path =
137  new BgpSecondaryPath(src_path->GetPeer(), src_path->GetPathId(),
138  src_path->GetSource(), new_attr,
139  src_path->GetFlags(), src_path->GetLabel());
140  replicated_path->SetReplicateInfo(src_table, source_rt);
141  dest_route->InsertPath(replicated_path);
142 
143  // Always trigger notification.
144  partition->Notify(dest_route);
145 
146  return dest_route;
147 }
148 
149 bool Inet6VpnTable::Export(RibOut *ribout, Route *route,
150  const RibPeerSet &peerset, UpdateInfoSList &uinfo_slist) {
151  BgpRoute *bgp_route = static_cast<BgpRoute *> (route);
152  UpdateInfo *uinfo = GetUpdateInfo(ribout, bgp_route, peerset);
153  if (!uinfo) {
154  return false;
155  }
156  uinfo_slist->push_front(*uinfo);
157 
158  return true;
159 }
160 
161 static void RegisterFactory() {
162  DB::RegisterFactory("bgp.l3vpn-inet6.0", &Inet6VpnTable::CreateTable);
163 }
static RouteDistinguisher GenerateDistinguisher(const BgpTable *src_table, const BgpPath *src_path)
as_t neighbor_as() const
Definition: bgp_attr.cc:1132
const RouteDistinguisher * GetRD() const
virtual bool IsXmppPeer() const =0
UpdateInfo * GetUpdateInfo(RibOut *ribout, BgpRoute *route, const RibPeerSet &peerset)
Definition: bgp_table.cc:578
bool RemoveSecondaryPath(const BgpRoute *src_rt, BgpPath::PathSource src, const IPeer *peer, uint32_t path_id)
Definition: bgp_route.cc:397
DBEntry * Find(const DBEntry *entry)
int prefixlen() const
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
virtual BgpRoute * TableFind(DBTablePartition *rtp, const DBRequestKey *prefix)
Definition: route.h:14
const uint32_t GetPathId() const
Definition: bgp_path.h:78
virtual bool IsRouterTypeBGPaaS() const =0
static Inet6VpnPrefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
const std::string & name() const
const RouteDistinguisher & source_rd() const
Definition: bgp_attr.h:896
virtual Address::Family family() const =0
uint32_t GetFlags() const
Definition: bgp_path.h:100
uint32_t as_t
Definition: bgp_common.h:21
BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr, ExtCommunityPtr extcomm)
Definition: bgp_attr.cc:1330
Definition: db.h:24
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
void SetReplicateInfo(const BgpTable *table, const BgpRoute *rt)
Definition: bgp_path.h:172
void Init()
Definition: db_table.cc:387
PathSource GetSource() const
Definition: bgp_path.h:103
Inet6VpnTable(DB *db, const std::string &name)
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:448
virtual const std::string & ToString() const =0
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *key) const
virtual std::unique_ptr< DBEntry > AllocEntryStr(const std::string &key) const
IPeer * GetPeer()
Definition: bgp_path.h:76
BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr, const RouteDistinguisher &source_rd)
Definition: bgp_attr.cc:1362
void ClearDelete()
Definition: db_entry.h:48
uint32_t GetLabel() const
Definition: bgp_path.h:89
virtual BgpServer * server()=0
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:60
virtual bool Export(RibOut *ribout, Route *route, const RibPeerSet &peerset, UpdateInfoSList &info_slist)
static DBTableBase * CreateTable(DB *db, const std::string &name)
const BgpAttr * GetOriginalAttr() const
Definition: bgp_path.h:88
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
BgpPath * FindSecondaryPath(BgpRoute *src_rt, BgpPath::PathSource src, const IPeer *peer, uint32_t path_id)
Definition: bgp_route.cc:372
BgpAttrDB * attr_db()
Definition: bgp_server.h:181
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
virtual size_t Hash(const DBEntry *entry) const
BgpPeer * FindNextPeer(const std::string &name=std::string())
Definition: bgp_server.cc:634
static void RegisterFactory()
static int PartitionCount()
Definition: db.cc:32
virtual void Add(DBEntry *entry)
static size_t HashFunction(const Inet6Prefix &addr)
Definition: inet6_table.cc:17
void Notify(DBEntryBase *entry)
virtual BgpRoute * RouteReplicate(BgpServer *server, BgpTable *src_table, BgpRoute *src_rt, const BgpPath *path, ExtCommunityPtr ptr)
bool IsZero() const
Definition: rd.h:43
Ip6Address addr() const
const Inet6VpnPrefix & GetPrefix() const
#define MODULE_INITIALIZER(Func)
Definition: util.h:61
static void RegisterFactory(const std::string &prefix, CreateFunction create_fn)
Definition: db.cc:24