OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inet6_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/bgp_server.h"
8 #include "bgp/bgp_update.h"
12 
13 Inet6Table::Inet6Table(DB *db, const std::string &name)
14  : BgpTable(db, name) {
15 }
16 
17 size_t Inet6Table::HashFunction(const Inet6Prefix &prefix) {
18  const Ip6Address::bytes_type &addr_bytes = prefix.ToBytes();
19  return boost::hash_range(addr_bytes.begin(), addr_bytes.end());
20 }
21 
22 std::unique_ptr<DBEntry> Inet6Table::AllocEntry(const DBRequestKey *key) const {
23  const RequestKey *rkey = static_cast<const RequestKey *>(key);
24  return std::unique_ptr<DBEntry> (new Inet6Route(rkey->prefix));
25 }
26 
27 std::unique_ptr<DBEntry> Inet6Table::AllocEntryStr(
28  const std::string &key_str) const {
29  Inet6Prefix prefix = Inet6Prefix::FromString(key_str);
30  return std::unique_ptr<DBEntry> (new Inet6Route(prefix));
31 }
32 
33 size_t Inet6Table::Hash(const DBEntry *entry) const {
34  const Inet6Route *route = static_cast<const Inet6Route *>(entry);
35  size_t value = HashFunction(route->GetPrefix());
36  return value % DB::PartitionCount();
37 }
38 
39 size_t Inet6Table::Hash(const DBRequestKey *key) const {
40  const RequestKey *rkey = static_cast<const RequestKey *>(key);
41  size_t value = HashFunction(rkey->prefix);
42  return value % DB::PartitionCount();
43 }
44 
46  const DBRequestKey *key) {
47  const RequestKey *rkey = static_cast<const RequestKey *>(key);
48  Inet6Route route(rkey->prefix);
49  return static_cast<BgpRoute *>(partition->Find(&route));
50 }
51 
52 DBTableBase *Inet6Table::CreateTable(DB *db, const std::string &name) {
53  Inet6Table *table = new Inet6Table(db, name);
54  table->Init();
55  return table;
56 }
57 
59  BgpRoute *src_rt, const BgpPath *path, ExtCommunityPtr community) {
60  assert((src_table->family() == Address::INET6) ||
61  (src_table->family() == Address::INET6VPN));
62 
63  Inet6Route *source = dynamic_cast<Inet6Route *>(src_rt);
64 
66 
67  boost::scoped_ptr<Inet6Prefix> prefix;
68  if (source) {
69  prefix.reset(new Inet6Prefix(source->GetPrefix().ip6_addr(),
70  source->GetPrefix().prefixlen()));
71  } else {
72  Inet6VpnRoute *vpn_route = dynamic_cast<Inet6VpnRoute *> (src_rt);
73  assert(vpn_route);
74  rd = vpn_route->GetPrefix().route_distinguisher();
75  prefix.reset(new Inet6Prefix(vpn_route->GetPrefix().addr(),
76  vpn_route->GetPrefix().prefixlen()));
77  }
78 
79  Inet6Route route(*prefix);
80  DBTablePartition *partition =
81  static_cast<DBTablePartition *>(GetTablePartition(&route));
82  BgpRoute *dest_route = static_cast<BgpRoute *>(partition->Find(&route));
83  if (dest_route == NULL) {
84  dest_route = new Inet6Route(route.GetPrefix());
85  partition->Add(dest_route);
86  } else {
87  dest_route->ClearDelete();
88  }
89 
90  // Replace the extended community with the one provided.
91  BgpAttrDB *attr_db = server->attr_db();
92  BgpAttrPtr new_attr = attr_db->ReplaceExtCommunityAndLocate(path->GetAttr(),
93  community);
94 
95  if (!source) {
96  new_attr = attr_db->ReplaceSourceRdAndLocate(new_attr.get(), rd);
97  }
98 
99  // Check whether there's already a path with the given peer and path id.
100  BgpPath *dest_path =
101  dest_route->FindSecondaryPath(src_rt, path->GetSource(),
102  path->GetPeer(), path->GetPathId());
103  if (dest_path != NULL) {
104  if ((new_attr != dest_path->GetOriginalAttr()) ||
105  (path->GetFlags() != dest_path->GetFlags()) ||
106  (path->GetLabel() != dest_path->GetLabel())) {
107  // Update Attributes and notify (if needed)
108  if (dest_path->NeedsResolution()) {
109  path_resolver()->StopPathResolution(partition->index(),
110  dest_path);
111  }
112  assert(dest_route->RemoveSecondaryPath(src_rt, path->GetSource(),
113  path->GetPeer(), path->GetPathId()));
114  } else {
115  return dest_route;
116  }
117  }
118 
119  BgpSecondaryPath *replicated_path =
120  new BgpSecondaryPath(path->GetPeer(), path->GetPathId(),
121  path->GetSource(), new_attr, path->GetFlags(), path->GetLabel());
122  replicated_path->SetReplicateInfo(src_table, src_rt);
123 
124  // For VPN to VRF replication, start path resolution if fast convergence is
125  // enabled and update path flag to indicate need for resolution.
126  if (!source && (server->IsNextHopCheckEnabled()) &&
127  (replicated_path->GetSource() == BgpPath::BGP_XMPP)) {
128  Address::Family family = replicated_path->GetAttr()->nexthop_family();
129  RoutingInstanceMgr *mgr = server->routing_instance_mgr();
130  RoutingInstance *master_ri = mgr->GetDefaultRoutingInstance();
131  BgpTable *table = master_ri->GetTable(family);
132  replicated_path->SetResolveNextHop();
133  path_resolver()->StartPathResolution(dest_route, replicated_path,
134  table);
135  }
136 
137  dest_route->InsertPath(replicated_path);
138 
139  // Notify the route even if the best path may not have changed. For XMPP
140  // peers, we support sending multiple ECMP next-hops for a single route.
141  //
142  // TODO(ananth): Can be optimized for changes that does not result in
143  // any change to ECMP list
144  partition->Notify(dest_route);
145 
146  return dest_route;
147 }
148 
149 bool Inet6Table::Export(RibOut *ribout, Route *route, const RibPeerSet &peerset,
150  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 
157  if (ribout->ExportPolicy().encoding == RibExportPolicy::BGP) {
158  BgpAttrDB *attr_db = routing_instance()->server()->attr_db();
159  // Strip ExtCommunity.
160  if (uinfo->roattr.attr()->ext_community()) {
161  BgpAttrPtr new_attr = attr_db->ReplaceExtCommunityAndLocate(
162  uinfo->roattr.attr(), NULL);
163  uinfo->roattr.set_attr(this, new_attr);
164  }
165 
166  // Strip OriginVnPath.
167  if (uinfo->roattr.attr()->origin_vn_path()) {
168  BgpAttrPtr new_attr = attr_db->ReplaceOriginVnPathAndLocate(
169  uinfo->roattr.attr(), NULL);
170  uinfo->roattr.set_attr(this, new_attr);
171  }
172  }
173  uinfo_slist->push_front(*uinfo);
174 
175  return true;
176 }
177 
179  if (routing_instance()->IsMasterRoutingInstance())
180  return NULL;
181  return (new PathResolver(this));
182 }
183 
184 static void RegisterFactory() {
186 }
virtual Address::Family family() const
Definition: inet6_table.h:36
bool IsNextHopCheckEnabled() const
Definition: bgp_server.cc:690
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *key) const
Definition: inet6_table.cc:22
BgpTable * GetTable(Address::Family fmly)
RibOutAttr roattr
Definition: bgp_update.h:100
const BgpAttr * attr() const
Definition: bgp_ribout.h:97
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
BgpServer * server()
DBEntry * Find(const DBEntry *entry)
int prefixlen() const
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
Family
Definition: address.h:24
const RibExportPolicy & ExportPolicy() const
Definition: bgp_ribout.h:308
Definition: route.h:14
void StartPathResolution(BgpRoute *route, const BgpPath *path, BgpTable *nh_table=NULL)
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:102
const uint32_t GetPathId() const
Definition: bgp_path.h:78
const OriginVnPath * origin_vn_path() const
Definition: bgp_attr.h:916
RoutingInstance * GetDefaultRoutingInstance()
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
static Inet6Prefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
Definition: inet6_route.cc:58
virtual PathResolver * CreatePathResolver()
Definition: inet6_table.cc:178
PathSource GetSource() const
Definition: bgp_path.h:103
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:448
void set_attr(const BgpTable *table, const BgpAttrPtr &attrp)
Definition: bgp_ribout.h:98
virtual BgpRoute * TableFind(DBTablePartition *partition, const DBRequestKey *rkey)
Definition: inet6_table.cc:45
Inet6Table(DB *db, const std::string &name)
Definition: inet6_table.cc:13
virtual std::unique_ptr< DBEntry > AllocEntryStr(const std::string &key) const
Definition: inet6_table.cc:27
IPeer * GetPeer()
Definition: bgp_path.h:76
BgpAttrPtr ReplaceSourceRdAndLocate(const BgpAttr *attr, const RouteDistinguisher &source_rd)
Definition: bgp_attr.cc:1362
const Ip6Address::bytes_type ToBytes() const
Definition: inet6_route.h:29
void ClearDelete()
Definition: db_entry.h:48
uint32_t GetLabel() const
Definition: bgp_path.h:89
void SetResolveNextHop()
Definition: bgp_path.h:129
Ip6Address ip6_addr() const
Definition: inet6_route.h:27
void InsertPath(BgpPath *path)
Definition: bgp_route.cc:60
const BgpAttr * GetOriginalAttr() const
Definition: bgp_path.h:88
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
virtual size_t Hash(const DBEntry *entry) const
Definition: inet6_table.cc:33
Address::Family nexthop_family() const
Definition: bgp_attr.cc:1124
BgpPath * FindSecondaryPath(BgpRoute *src_rt, BgpPath::PathSource src, const IPeer *peer, uint32_t path_id)
Definition: bgp_route.cc:372
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:915
BgpAttrDB * attr_db()
Definition: bgp_server.h:181
const RouteDistinguisher & route_distinguisher() const
void StopPathResolution(int part_id, const BgpPath *path)
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
static void RegisterFactory()
Definition: inet6_table.cc:184
int prefixlen() const
Definition: inet6_route.h:33
static int PartitionCount()
Definition: db.cc:32
virtual void Add(DBEntry *entry)
static size_t HashFunction(const Inet6Prefix &addr)
Definition: inet6_table.cc:17
bool NeedsResolution() const
Definition: bgp_path.h:135
const Inet6Prefix & GetPrefix() const
Definition: inet6_route.h:80
void Notify(DBEntryBase *entry)
Ip6Address addr() const
const Inet6VpnPrefix & GetPrefix() const
BgpAttrPtr ReplaceOriginVnPathAndLocate(const BgpAttr *attr, OriginVnPathPtr ovnpath)
Definition: bgp_attr.cc:1338
#define MODULE_INITIALIZER(Func)
Definition: util.h:61
BgpRoute * RouteReplicate(BgpServer *server, BgpTable *src_tbl, BgpRoute *src_rt, const BgpPath *path, ExtCommunityPtr ptr)
Definition: inet6_table.cc:58
static DBTableBase * CreateTable(DB *db, const std::string &name)
Definition: inet6_table.cc:52
PathResolver * path_resolver()
Definition: bgp_table.h:153
static void RegisterFactory(const std::string &prefix, CreateFunction create_fn)
Definition: db.cc:24
int index() const
virtual bool Export(RibOut *ribout, Route *route, const RibPeerSet &peerset, UpdateInfoSList &info_slist)
Definition: inet6_table.cc:149