summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c138
1 files changed, 110 insertions, 28 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 390eb44eb..7a6b80f3a 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1001,6 +1001,7 @@ static bool bgp_tm_status_connected;
static bool bgp_tm_chunk_obtained;
#define BGP_FLOWSPEC_TABLE_CHUNK 100000
static uint32_t bgp_tm_min, bgp_tm_max, bgp_tm_chunk_size;
+struct bgp *bgp_tm_bgp;
static int bgp_zebra_tm_connect(struct thread *t)
{
@@ -1024,8 +1025,11 @@ static int bgp_zebra_tm_connect(struct thread *t)
if (!bgp_tm_chunk_obtained) {
if (bgp_zebra_get_table_range(bgp_tm_chunk_size,
&bgp_tm_min,
- &bgp_tm_max) >= 0)
+ &bgp_tm_max) >= 0) {
bgp_tm_chunk_obtained = true;
+ /* parse non installed entries */
+ bgp_zebra_announce_table(bgp_tm_bgp, AFI_IP, SAFI_FLOWSPEC);
+ }
}
}
thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
@@ -1033,6 +1037,11 @@ static int bgp_zebra_tm_connect(struct thread *t)
return 0;
}
+bool bgp_zebra_tm_chunk_obtained(void)
+{
+ return bgp_tm_chunk_obtained;
+}
+
uint32_t bgp_zebra_tm_get_id(void)
{
static int table_id;
@@ -1042,7 +1051,7 @@ uint32_t bgp_zebra_tm_get_id(void)
return bgp_tm_min++;
}
-void bgp_zebra_init_tm_connect(void)
+void bgp_zebra_init_tm_connect(struct bgp *bgp)
{
int delay = 1;
@@ -1054,6 +1063,7 @@ void bgp_zebra_init_tm_connect(void)
bgp_tm_chunk_obtained = false;
bgp_tm_min = bgp_tm_max = 0;
bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK;
+ bgp_tm_bgp = bgp;
thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
&bgp_tm_thread_connect);
}
@@ -1962,6 +1972,7 @@ static int rule_notify_owner(int command, struct zclient *zclient,
zlog_debug("%s: Received RULE_INSTALLED",
__PRETTY_FUNCTION__);
break;
+ case ZAPI_RULE_FAIL_REMOVE:
case ZAPI_RULE_REMOVED:
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received RULE REMOVED",
@@ -1987,8 +1998,8 @@ static int ipset_notify_owner(int command, struct zclient *zclient,
bgp_pbim = bgp_pbr_match_ipset_lookup(vrf_id, unique);
if (!bgp_pbim) {
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("%s: Fail to look BGP match (%u)",
- __PRETTY_FUNCTION__, unique);
+ zlog_debug("%s: Fail to look BGP match ( %u %u)",
+ __PRETTY_FUNCTION__, note, unique);
return 0;
}
@@ -2007,6 +2018,7 @@ static int ipset_notify_owner(int command, struct zclient *zclient,
zlog_debug("%s: Received IPSET_INSTALLED",
__PRETTY_FUNCTION__);
break;
+ case ZAPI_IPSET_FAIL_REMOVE:
case ZAPI_IPSET_REMOVED:
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received IPSET REMOVED",
@@ -2036,8 +2048,8 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
unique);
if (!bgp_pbime) {
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("%s: Fail to look BGP match entry (%u)",
- __PRETTY_FUNCTION__, unique);
+ zlog_debug("%s: Fail to look BGP match entry (%u %u)",
+ __PRETTY_FUNCTION__, note, unique);
return 0;
}
@@ -2050,12 +2062,22 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
bgp_pbime->install_in_progress = false;
break;
case ZAPI_IPSET_ENTRY_INSTALLED:
- bgp_pbime->installed = true;
- bgp_pbime->install_in_progress = false;
- if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
- __PRETTY_FUNCTION__);
+ {
+ struct bgp_info *bgp_info;
+ struct bgp_info_extra *extra;
+
+ bgp_pbime->installed = true;
+ bgp_pbime->install_in_progress = false;
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
+ __PRETTY_FUNCTION__);
+ /* link bgp_info to bpme */
+ bgp_info = (struct bgp_info *)bgp_pbime->bgp_info;
+ extra = bgp_info_extra_get(bgp_info);
+ extra->bgp_fs_pbr = (void *)bgp_pbime;
+ }
break;
+ case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
case ZAPI_IPSET_ENTRY_REMOVED:
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received IPSET_ENTRY_REMOVED",
@@ -2080,8 +2102,8 @@ static int iptable_notify_owner(int command, struct zclient *zclient,
bgpm = bgp_pbr_match_iptable_lookup(vrf_id, unique);
if (!bgpm) {
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("%s: Fail to look BGP iptable (%u)",
- __PRETTY_FUNCTION__, unique);
+ zlog_debug("%s: Fail to look BGP iptable (%u %u)",
+ __PRETTY_FUNCTION__, note, unique);
return 0;
}
switch (note) {
@@ -2100,6 +2122,7 @@ static int iptable_notify_owner(int command, struct zclient *zclient,
__PRETTY_FUNCTION__);
bgpm->action->refcnt++;
break;
+ case ZAPI_IPTABLE_FAIL_REMOVE:
case ZAPI_IPTABLE_REMOVED:
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received IPTABLE REMOVED",
@@ -2167,6 +2190,12 @@ static void bgp_encode_pbr_ipset_entry_match(struct stream *s,
stream_putc(s, pbime->dst.family);
stream_putc(s, pbime->dst.prefixlen);
stream_put(s, &pbime->dst.u.prefix, prefix_blen(&pbime->dst));
+
+ stream_putw(s, pbime->src_port_min);
+ stream_putw(s, pbime->src_port_max);
+ stream_putw(s, pbime->dst_port_min);
+ stream_putw(s, pbime->dst_port_max);
+ stream_putc(s, pbime->proto);
}
static void bgp_encode_pbr_iptable_match(struct stream *s,
@@ -2490,8 +2519,10 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra, bool install)
if (pbra->install_in_progress)
return;
- zlog_debug("%s: table %d fwmark %d %d", __PRETTY_FUNCTION__,
- pbra->table_id, pbra->fwmark, install);
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("%s: table %d fwmark %d %d",
+ __PRETTY_FUNCTION__,
+ pbra->table_id, pbra->fwmark, install);
s = zclient->obuf;
stream_reset(s);
@@ -2513,8 +2544,10 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
if (pbrim->install_in_progress)
return;
- zlog_debug("%s: name %s type %d %d", __PRETTY_FUNCTION__,
- pbrim->ipset_name, pbrim->type, install);
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("%s: name %s type %d %d",
+ __PRETTY_FUNCTION__,
+ pbrim->ipset_name, pbrim->type, install);
s = zclient->obuf;
stream_reset(s);
@@ -2539,9 +2572,10 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
if (pbrime->install_in_progress)
return;
- zlog_debug("%s: name %s %d %d", __PRETTY_FUNCTION__,
- pbrime->backpointer->ipset_name,
- pbrime->unique, install);
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("%s: name %s %d %d", __PRETTY_FUNCTION__,
+ pbrime->backpointer->ipset_name,
+ pbrime->unique, install);
s = zclient->obuf;
stream_reset(s);
@@ -2559,16 +2593,56 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
pbrime->install_in_progress = true;
}
+static void bgp_encode_pbr_interface_list(struct bgp *bgp, struct stream *s)
+{
+ struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg;
+ struct bgp_pbr_interface_head *head;
+ struct bgp_pbr_interface *pbr_if;
+ struct interface *ifp;
+
+ if (!bgp_pbr_cfg)
+ return;
+ head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
+
+ RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
+ ifp = if_lookup_by_name(pbr_if->name, bgp->vrf_id);
+ if (ifp)
+ stream_putl(s, ifp->ifindex);
+ }
+}
+
+static int bgp_pbr_get_ifnumber(struct bgp *bgp)
+{
+ struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg;
+ struct bgp_pbr_interface_head *head;
+ struct bgp_pbr_interface *pbr_if;
+ int cnt = 0;
+
+ if (!bgp_pbr_cfg)
+ return 0;
+ head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
+
+ RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
+ if (if_lookup_by_name(pbr_if->name, bgp->vrf_id))
+ cnt++;
+ }
+ return cnt;
+}
+
void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
struct bgp_pbr_match *pbm,
bool install)
{
struct stream *s;
+ int ret = 0;
+ int nb_interface;
if (pbm->install_iptable_in_progress)
return;
- zlog_debug("%s: name %s type %d mark %d %d", __PRETTY_FUNCTION__,
- pbm->ipset_name, pbm->type, pba->fwmark, install);
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("%s: name %s type %d mark %d %d",
+ __PRETTY_FUNCTION__, pbm->ipset_name,
+ pbm->type, pba->fwmark, install);
s = zclient->obuf;
stream_reset(s);
@@ -2578,11 +2652,17 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
VRF_DEFAULT);
bgp_encode_pbr_iptable_match(s, pba, pbm);
-
+ nb_interface = bgp_pbr_get_ifnumber(pba->bgp);
+ stream_putl(s, nb_interface);
+ if (nb_interface)
+ bgp_encode_pbr_interface_list(pba->bgp, s);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install) {
- pbm->install_iptable_in_progress = true;
- pba->refcnt++;
+ ret = zclient_send_message(zclient);
+ if (install) {
+ if (ret)
+ pba->refcnt++;
+ else
+ pbm->install_iptable_in_progress = true;
}
}
@@ -2626,7 +2706,8 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
inet_ntop(AF_INET, &(nh->gate.ipv4), buff, INET_ADDRSTRLEN);
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_info("BGP: sending default route to %s table %d (redirect IP)",
+ zlog_info("BGP: %s default route to %s table %d (redirect IP)",
+ announce ? "adding" : "withdrawing",
buff, table_id);
zclient_route_send(announce ? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE,
@@ -2648,7 +2729,8 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
api_nh->type = NEXTHOP_TYPE_IFINDEX;
api_nh->ifindex = ifp->ifindex;
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_info("BGP: sending default route to %s table %d (redirect VRF)",
+ zlog_info("BGP: %s default route to %s table %d (redirect VRF)",
+ announce ? "adding" : "withdrawing",
vrf->name, table_id);
zclient_route_send(announce ? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE,