OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inetvpn_table.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include "bgp/ipeer.h"
8 #include "bgp/bgp_server.h"
9 #include "bgp/bgp_update.h"
10 #include "bgp/inet/inet_table.h"
11 #include "bgp/bgp_peer.h"
13 #include "net/rd.h"
14 
15 using std::unique_ptr;
16 using std::string;
17 
18 InetVpnTable::InetVpnTable(DB *db, const string &name)
19  : BgpTable(db, name) {
20 }
21 
22 unique_ptr<DBEntry> InetVpnTable::AllocEntry(const DBRequestKey *key) const {
23  const RequestKey *pfxkey = static_cast<const RequestKey *>(key);
24  return unique_ptr<DBEntry> (new InetVpnRoute(pfxkey->prefix));
25 }
26 
27 
28 unique_ptr<DBEntry> InetVpnTable::AllocEntryStr(const string &key_str) const {
29  InetVpnPrefix prefix = InetVpnPrefix::FromString(key_str);
30  return unique_ptr<DBEntry> (new InetVpnRoute(prefix));
31 }
32 
33 size_t InetVpnTable::Hash(const DBEntry *entry) const {
34  const InetVpnRoute *rt_entry = static_cast<const InetVpnRoute *>(entry);
35  const InetVpnPrefix &inetvpnprefix = rt_entry->GetPrefix();
36  Ip4Prefix prefix(inetvpnprefix.addr(), inetvpnprefix.prefixlen());
37  size_t value = InetTable::HashFunction(prefix);
38  return value % DB::PartitionCount();
39 }
40 
41 size_t InetVpnTable::Hash(const DBRequestKey *key) const {
42  const RequestKey *rkey = static_cast<const RequestKey *>(key);
43  Ip4Prefix prefix(rkey->prefix.addr(), rkey->prefix.prefixlen());
44  size_t value = InetTable::HashFunction(prefix);
45  return value % DB::PartitionCount();
46 }
47 
49  const DBRequestKey *prefix) {
50  const RequestKey *pfxkey = static_cast<const RequestKey *>(prefix);
51  InetVpnRoute rt_key(pfxkey->prefix);
52  return static_cast<BgpRoute *>(rtp->Find(&rt_key));
53 }
54 
55 DBTableBase *InetVpnTable::CreateTable(DB *db, const string &name) {
56  InetVpnTable *table = new InetVpnTable(db, name);
57  table->Init();
58  return table;
59 }
60 
62  const BgpTable *src_table, const BgpPath *src_path) {
63  const RouteDistinguisher &source_rd = src_path->GetAttr()->source_rd();
64  if (!src_path->GetPeer() || !(src_path->GetPeer()->IsRouterTypeBGPaaS())){
65  if (!source_rd.IsZero())
66  return source_rd;
67 
68  assert(!src_path->GetPeer() || !src_path->GetPeer()->IsXmppPeer());
69  const RoutingInstance *src_instance = src_table->routing_instance();
70  return *src_instance->GetRD();
71  }
72  boost::system::error_code ec;
73  Ip4Address addr = Ip4Address::from_string(src_path->GetPeer()->ToString(), ec);
74  if ((ec.value() != 0)) {
75  if (!source_rd.IsZero())
76  return source_rd;
77 
78  assert(!src_path->GetPeer() || !src_path->GetPeer()->IsXmppPeer());
79  const RoutingInstance *src_instance = src_table->routing_instance();
80  return *src_instance->GetRD();
81  } else {
82  int vrf_id = 0;
83  RouteDistinguisher new_source_rd = RouteDistinguisher(addr.to_ulong(), vrf_id);
84  return new_source_rd;
85  }
86 }
87 
89  BgpTable *src_table, BgpRoute *src_rt, const BgpPath *src_path,
90  ExtCommunityPtr community) {
91  assert(src_table->family() == Address::INET);
92 
93  InetRoute *inet = dynamic_cast<InetRoute *> (src_rt);
94  assert(inet);
95 
96  const RouteDistinguisher &rd = GenerateDistinguisher(src_table, src_path);
97 
98  InetVpnPrefix vpn(rd, inet->GetPrefix().ip4_addr(),
99  inet->GetPrefix().prefixlen());
100 
101  InetVpnRoute rt_key(vpn);
102 
103  DBTablePartition *rtp =
104  static_cast<DBTablePartition *>(GetTablePartition(&rt_key));
105  BgpRoute *dest_route = static_cast<BgpRoute *>(rtp->Find(&rt_key));
106  if (dest_route == NULL) {
107  dest_route = new InetVpnRoute(vpn);
108  rtp->Add(dest_route);
109  } else {
110  dest_route->ClearDelete();
111  }
112 
113  BgpAttrDB *attr_db = server->attr_db();
114 
115  BgpAttrPtr new_attr =
116  server->attr_db()->ReplaceExtCommunityAndLocate(src_path->GetAttr(),
117  community);
118  new_attr = attr_db->ReplaceSourceRdAndLocate(new_attr.get(), rd);
119  // Check whether there's already a path with the given peer and path id.
120  BgpPath *dest_path =
121  dest_route->FindSecondaryPath(src_rt, src_path->GetSource(),
122  src_path->GetPeer(),
123  src_path->GetPathId());
124  if (dest_path != NULL) {
125  if ((new_attr != dest_path->GetOriginalAttr()) ||
126  (src_path->GetFlags() != dest_path->GetFlags()) ||
127  (src_path->GetLabel() != dest_path->GetLabel())) {
128  // Update Attributes and notify (if needed)
129  assert(dest_route->RemoveSecondaryPath(src_rt,
130  src_path->GetSource(), src_path->GetPeer(),
131  src_path->GetPathId()));
132  } else {
133  return dest_route;
134  }
135  }
136 
137  // Create replicated path and insert it on the route
138  BgpSecondaryPath *replicated_path =
139  new BgpSecondaryPath(src_path->GetPeer(), src_path->GetPathId(),
140  src_path->GetSource(), new_attr,
141  src_path->GetFlags(), src_path->GetLabel());
142  replicated_path->SetReplicateInfo(src_table, src_rt);
143  dest_route->InsertPath(replicated_path);
144 
145  // Always trigger notification.
146  rtp->Notify(dest_route);
147 
148  // Update corresponding route's extended communities in inet.0 table.
149  InetTable *inet_table =
150  dynamic_cast<InetTable *>(routing_instance()->GetTable(Address::INET));
151  InetVpnRoute *inetvpn_route = dynamic_cast<InetVpnRoute *>(dest_route);
152  inet_table->UpdateRoute(inetvpn_route->GetPrefix(), src_path->GetPeer(),
153  new_attr);
154  return dest_route;
155 }
156 
157 bool InetVpnTable::Export(RibOut *ribout, Route *route,
158  const RibPeerSet &peerset, UpdateInfoSList &uinfo_slist) {
159  BgpRoute *bgp_route = static_cast<BgpRoute *> (route);
160  UpdateInfo *uinfo = GetUpdateInfo(ribout, bgp_route, peerset);
161  if (!uinfo) return false;
162  uinfo_slist->push_front(*uinfo);
163 
164  return true;
165 }
166 
167 static void RegisterFactory() {
169 }
BgpTable * GetTable(Address::Family fmly)
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)
InetVpnTable(DB *db, const std::string &name)
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
Ip4Address addr() const
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *key) const
Definition: route.h:14
static RouteDistinguisher GenerateDistinguisher(const BgpTable *src_table, const BgpPath *src_path)
void UpdateRoute(const InetVpnPrefix &inetvpn_prefix, const IPeer *peer, BgpAttrPtr inetvpn_attrp)
Definition: inet_table.cc:352
const InetVpnPrefix & GetPrefix() const
Definition: inetvpn_route.h:27
const uint32_t GetPathId() const
Definition: bgp_path.h:78
virtual bool IsRouterTypeBGPaaS() const =0
virtual BgpRoute * TableFind(DBTablePartition *rtp, const DBRequestKey *prefix)
static InetVpnPrefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
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
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
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:448
virtual const std::string & ToString() const =0
IPeer * GetPeer()
Definition: bgp_path.h:76
BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr, const RouteDistinguisher &source_rd)
Definition: bgp_attr.cc:1362
static size_t HashFunction(const Ip4Prefix &addr)
Definition: inet_table.cc:28
void ClearDelete()
Definition: db_entry.h:48
uint32_t GetLabel() const
Definition: bgp_path.h:89
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:60
virtual std::unique_ptr< DBEntry > AllocEntryStr(const std::string &key) const
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 BgpRoute * RouteReplicate(BgpServer *server, BgpTable *src_table, BgpRoute *src_rt, const BgpPath *path, ExtCommunityPtr ptr)
static DBTableBase * CreateTable(DB *db, const std::string &name)
static void RegisterFactory()
static int PartitionCount()
Definition: db.cc:32
virtual void Add(DBEntry *entry)
int prefixlen() const
void Notify(DBEntryBase *entry)
bool IsZero() const
Definition: rd.h:43
virtual bool Export(RibOut *ribout, Route *route, const RibPeerSet &peerset, UpdateInfoSList &info_slist)
virtual size_t Hash(const DBEntry *entry) const
#define MODULE_INITIALIZER(Func)
Definition: util.h:61
static void RegisterFactory(const std::string &prefix, CreateFunction create_fn)
Definition: db.cc:24