OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
controller_vrf_export.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/uuid/uuid_io.hpp>
6 
7 #include <cmn/agent_cmn.h>
8 #include <oper/route_common.h>
10 #include <oper/vrf.h>
11 #include <oper/mirror_table.h>
12 
18 #include <controller/controller_types.h>
19 
20 VrfExport::State::State() : DBState(), exported_(false),
21  force_chg_(false), rt_export_(), last_sequence_number_(0) {
22 };
23 
25 };
26 
27 bool VrfExport::State::IsExportable(uint64_t sequence_number) {
28  // Sequence number passed in argument is of channel to which this state
29  // belongs. Once channel sends the vrf subscription after flap/fresh
30  // connection, state's sequence number will be updated to that of channel.
31  // After this all routes in this VRF become eligible for export.
32  // This is needed as control-node mandates that VRF is subscribed before any
33  // route is seen in same else it will again flap the
34  // connection(intentionally).
35  // Note: In case of flaps etc CN removes VRF subscription.
36  // This sequence number macthing helps in making sure that VRF sub is
37  // sent before any route is published.
38  return (last_sequence_number_ != sequence_number);
39 }
40 
41 void VrfExport::Notify(const Agent *agent, AgentXmppChannel *bgp_xmpp_peer,
42  DBTablePartBase *partition, DBEntryBase *e) {
43 
44  BgpPeer *bgp_peer = static_cast<BgpPeer *>(bgp_xmpp_peer->bgp_peer_id());
45  VrfEntry *vrf = static_cast<VrfEntry *>(e);
46  //PBB VRF is implictly created, agent is not supposed to send RI
47  //subscription message since control-node will not be aware of this RI
48  //We still want to set a state and subscribe for bridge table for
49  //building ingress replication tree
50  bool send_subscribe = vrf->ShouldExportRoute();
51 
52  uint32_t instance_id = vrf->rd();
53  //Instance ID being zero is possible because of VN unavailability and VRF
54  //ending up with NULL VRF. Reason being config sequence.
55  //So seeing 0 instance_id delete the state so that resubscribe can be done
56  //with new id and then re-export all route.
57  //Note: Assumption is that instance id will never change from non zero to
58  //some other non zero value.
59  //Also Instance ID check is for TSN and TA only.
60  bool deleted = (vrf->IsDeleted()) || (instance_id == VrfEntry::kInvalidIndex);
61 
62  if (deleted) {
63  bgp_peer->DeleteVrfState(partition, e);
64  if (!AgentXmppChannel::IsXmppChannelActive(agent, bgp_xmpp_peer)) {
65  return;
66  }
67  if (bgp_peer) {
68  CONTROLLER_TRACE(Trace, bgp_peer->GetName(), vrf->GetName(),
69  "VRF deleted, remove state");
70  bgp_peer->DeleteVrfState(partition, e);
71  }
72  return;
73  }
74 
75  if (!AgentXmppChannel::IsBgpPeerActive(agent, bgp_xmpp_peer))
76  return;
77 
79  State *state = static_cast<State *>(vrf->GetState(partition->parent(), id));
80  uint8_t table_type;
81  if (state == NULL) {
82  state = new State();
83  state->exported_ = false;
84  state->mcast_exported_ = false;
85  state->force_chg_ = true;
86  vrf->SetState(partition->parent(), id, state);
87 
88  // Dont export routes belonging to Fabric VRF table
89  for (table_type = (Agent::INVALID + 1);
90  table_type < Agent::ROUTE_TABLE_MAX; table_type++) {
91  state->rt_export_[table_type] =
93  static_cast<AgentRouteTable *>
94  (vrf->GetRouteTable(table_type)),
95  bgp_xmpp_peer);
96  }
97  }
98 
99  if (state->last_sequence_number_ == bgp_xmpp_peer->sequence_number()) {
100  state->force_chg_ = false;
101  } else {
102  state->last_sequence_number_ = bgp_xmpp_peer->sequence_number();
103  }
104 
105  if (send_subscribe == false) {
106  state->force_chg_ = false;
107  }
108 
109  if (send_subscribe && ((state->exported_ == false) ||
110  (state->force_chg_ == true))) {
111  if (AgentXmppChannel::ControllerSendSubscribe(bgp_xmpp_peer, vrf,
112  true)) {
113  CONTROLLER_TRACE(Trace, bgp_peer->GetName(), vrf->GetName(),
114  "Subscribe");
115 
116  state->exported_ = true;
117  if (state->force_chg_ == true) {
118  bgp_peer->route_walker()->StartRouteWalk(vrf, true,
120  state->force_chg_ = false;
121 
122  if (Agent::GetInstance()->mulitcast_builder() == bgp_xmpp_peer) {
123  state->mcast_exported_ = true;
124  } else {
125  state->mcast_exported_ = false;
126  }
127  }
128  return;
129  }
130  } else {
131  if (send_subscribe &&
132  (Agent::GetInstance()->mulitcast_builder() == bgp_xmpp_peer) &&
133  !state->mcast_exported_) {
134  // When Agent switches to a new multicast builder, we have to
135  // send multicast subscribe to the new multicast builder. Otherwise,
136  // Agent can get stuck with old multicast tree affecting BUM
137  // traffic.
138  bgp_peer->route_walker()->StartRouteWalk(vrf, true,
140  state->mcast_exported_ = true;
141  } else if (send_subscribe &&
142  Agent::GetInstance()->mulitcast_builder() != bgp_xmpp_peer) {
143  // If it is not the multicast builder, mark the flag false so that
144  // if it becomes multicast builder we notify mutlcast routes
145  state->mcast_exported_ = false;
146  } else {
147  CONTROLLER_TRACE(Trace, bgp_peer->GetName(), vrf->GetName(),
148  "Already subscribed");
149  }
150  }
151 }
const std::string & GetName() const
Definition: peer.h:86
bool IsExportable(uint64_t sequence_number)
static Agent * GetInstance()
Definition: agent.h:436
Definition: vrf.h:86
void StartRouteWalk(VrfEntry *vrf, bool associate, Type type)
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
bool IsDeleted() const
Definition: db_entry.h:49
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
int ListenerId
Definition: db_table.h:62
DBTableBase * parent()
const string & GetName() const
Definition: vrf.h:100
Definition: agent.h:358
static bool IsXmppChannelActive(const Agent *agent, AgentXmppChannel *peer)
uint64_t sequence_number() const
Definition: trace.h:220
DBTableBase::ListenerId GetVrfExportListenerId()
Definition: peer.h:171
ControllerRouteWalker * route_walker() const
Definition: peer.cc:242
void DeleteVrfState(DBTablePartBase *partition, DBEntryBase *entry)
Definition: peer.cc:259
static const uint32_t kInvalidIndex
Definition: vrf.h:88
AgentRouteTable * GetRouteTable(uint8_t table_type) const
Definition: vrf.cc:285
RouteExport * rt_export_[Agent::ROUTE_TABLE_MAX]
static RouteExport * Init(AgentRouteTable *table, AgentXmppChannel *bgp_xmpp_peer)
BgpPeer * bgp_peer_id()
int rd() const
Definition: vrf.h:220
static void Notify(const Agent *agent, AgentXmppChannel *, DBTablePartBase *partition, DBEntryBase *e)
#define CONTROLLER_TRACE(obj,...)
bool ShouldExportRoute() const
Definition: vrf.h:132
static bool ControllerSendSubscribe(AgentXmppChannel *peer, VrfEntry *vrf, bool subscribe)
static bool IsBgpPeerActive(const Agent *agent, AgentXmppChannel *peer)