Skip to content

Commit c16a0a6

Browse files
committed
bgpd: handle configuration of iptables with zebra
The API for filling in an IPTABLE_ADD and IPTABLE_DELETE message. Also, the API is handling the notification callback, so as to know if zebra managed to add or delete the relevant iptable entry. Signed-off-by: Philippe Guibert <[email protected]>
1 parent 45918cf commit c16a0a6

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

bgpd/bgp_zebra.c

+92
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,49 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
20472047
return 0;
20482048
}
20492049

2050+
static int iptable_notify_owner(int command, struct zclient *zclient,
2051+
zebra_size_t length, vrf_id_t vrf_id)
2052+
{
2053+
uint32_t unique;
2054+
enum zapi_iptable_notify_owner note;
2055+
struct bgp_pbr_match *bgpm;
2056+
2057+
if (!zapi_iptable_notify_decode(
2058+
zclient->ibuf,
2059+
&unique,
2060+
&note))
2061+
return -1;
2062+
bgpm = bgp_pbr_match_iptable_lookup(vrf_id, unique);
2063+
if (!bgpm) {
2064+
if (BGP_DEBUG(zebra, ZEBRA))
2065+
zlog_debug("%s: Fail to look BGP iptable (%u)",
2066+
__PRETTY_FUNCTION__, unique);
2067+
return 0;
2068+
}
2069+
switch (note) {
2070+
case ZAPI_IPTABLE_FAIL_INSTALL:
2071+
if (BGP_DEBUG(zebra, ZEBRA))
2072+
zlog_debug("%s: Received IPTABLE_FAIL_INSTALL",
2073+
__PRETTY_FUNCTION__);
2074+
bgpm->installed_in_iptable = false;
2075+
bgpm->install_iptable_in_progress = false;
2076+
break;
2077+
case ZAPI_IPTABLE_INSTALLED:
2078+
bgpm->installed_in_iptable = true;
2079+
bgpm->install_iptable_in_progress = false;
2080+
if (BGP_DEBUG(zebra, ZEBRA))
2081+
zlog_debug("%s: Received IPTABLE_INSTALLED",
2082+
__PRETTY_FUNCTION__);
2083+
break;
2084+
case ZAPI_IPTABLE_REMOVED:
2085+
if (BGP_DEBUG(zebra, ZEBRA))
2086+
zlog_debug("%s: Received IPTABLE REMOVED",
2087+
__PRETTY_FUNCTION__);
2088+
break;
2089+
}
2090+
return 0;
2091+
}
2092+
20502093
static void bgp_encode_pbr_rule_action(struct stream *s,
20512094
struct bgp_pbr_action *pbra)
20522095
{
@@ -2107,6 +2150,29 @@ static void bgp_encode_pbr_ipset_entry_match(struct stream *s,
21072150
stream_put(s, &pbime->dst.u.prefix, prefix_blen(&pbime->dst));
21082151
}
21092152

2153+
static void bgp_encode_pbr_iptable_match(struct stream *s,
2154+
struct bgp_pbr_action *bpa,
2155+
struct bgp_pbr_match *pbm)
2156+
{
2157+
stream_putl(s, pbm->unique2);
2158+
2159+
stream_putl(s, pbm->type);
2160+
2161+
stream_putl(s, pbm->flags);
2162+
2163+
/* TODO: correlate with what is contained
2164+
* into bgp_pbr_action.
2165+
* currently only forward supported
2166+
*/
2167+
if (bpa->nh.type == NEXTHOP_TYPE_BLACKHOLE)
2168+
stream_putl(s, ZEBRA_IPTABLES_DROP);
2169+
else
2170+
stream_putl(s, ZEBRA_IPTABLES_FORWARD);
2171+
stream_putl(s, bpa->fwmark);
2172+
stream_put(s, pbm->ipset_name,
2173+
ZEBRA_IPSET_NAME_SIZE);
2174+
}
2175+
21102176
/* BGP has established connection with Zebra. */
21112177
static void bgp_zebra_connected(struct zclient *zclient)
21122178
{
@@ -2369,6 +2435,7 @@ void bgp_zebra_init(struct thread_master *master)
23692435
zclient->rule_notify_owner = rule_notify_owner;
23702436
zclient->ipset_notify_owner = ipset_notify_owner;
23712437
zclient->ipset_entry_notify_owner = ipset_entry_notify_owner;
2438+
zclient->iptable_notify_owner = iptable_notify_owner;
23722439
}
23732440

23742441
void bgp_zebra_destroy(void)
@@ -2459,3 +2526,28 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
24592526
if (!zclient_send_message(zclient) && install)
24602527
pbrime->install_in_progress = true;
24612528
}
2529+
2530+
void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
2531+
struct bgp_pbr_match *pbm,
2532+
bool install)
2533+
{
2534+
struct stream *s;
2535+
2536+
if (pbm->install_iptable_in_progress)
2537+
return;
2538+
zlog_debug("%s: name %s type %d mark %d %d", __PRETTY_FUNCTION__,
2539+
pbm->ipset_name, pbm->type, pba->fwmark, install);
2540+
s = zclient->obuf;
2541+
stream_reset(s);
2542+
2543+
zclient_create_header(s,
2544+
install ? ZEBRA_IPTABLE_ADD :
2545+
ZEBRA_IPTABLE_DELETE,
2546+
VRF_DEFAULT);
2547+
2548+
bgp_encode_pbr_iptable_match(s, pba, pbm);
2549+
2550+
stream_putw_at(s, 0, stream_get_endp(s));
2551+
if (!zclient_send_message(zclient) && install)
2552+
pbm->install_iptable_in_progress = true;
2553+
}

bgpd/bgp_zebra.h

+3
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,8 @@ extern void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim,
7979
bool install);
8080
extern void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
8181
bool install);
82+
extern void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
83+
struct bgp_pbr_match *pbm,
84+
bool install);
8285

8386
#endif /* _QUAGGA_BGP_ZEBRA_H */

lib/zclient.c

+36
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,26 @@ bool zapi_ipset_entry_notify_decode(struct stream *s,
13741374
return false;
13751375
}
13761376

1377+
bool zapi_iptable_notify_decode(struct stream *s,
1378+
uint32_t *unique,
1379+
enum zapi_iptable_notify_owner *note)
1380+
{
1381+
uint32_t uni;
1382+
1383+
STREAM_GET(note, s, sizeof(*note));
1384+
1385+
STREAM_GETL(s, uni);
1386+
1387+
if (zclient_debug)
1388+
zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1389+
*unique = uni;
1390+
1391+
return true;
1392+
1393+
stream_failure:
1394+
return false;
1395+
}
1396+
13771397
struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
13781398
{
13791399
struct nexthop *n = nexthop_new();
@@ -2765,6 +2785,22 @@ static int zclient_read(struct thread *thread)
27652785
(*zclient->label_chunk)(command, zclient, length,
27662786
vrf_id);
27672787
break;
2788+
case ZEBRA_IPSET_NOTIFY_OWNER:
2789+
if (zclient->ipset_notify_owner)
2790+
(*zclient->ipset_notify_owner)(command, zclient, length,
2791+
vrf_id);
2792+
break;
2793+
case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
2794+
if (zclient->ipset_entry_notify_owner)
2795+
(*zclient->ipset_entry_notify_owner)(command,
2796+
zclient, length,
2797+
vrf_id);
2798+
break;
2799+
case ZEBRA_IPTABLE_NOTIFY_OWNER:
2800+
if (zclient->iptable_notify_owner)
2801+
(*zclient->iptable_notify_owner)(command,
2802+
zclient, length,
2803+
vrf_id);
27682804
default:
27692805
break;
27702806
}

lib/zclient.h

+7
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ struct zclient {
258258
struct zclient *zclient,
259259
uint16_t length,
260260
vrf_id_t vrf_id);
261+
int (*iptable_notify_owner)(int command,
262+
struct zclient *zclient,
263+
uint16_t length,
264+
vrf_id_t vrf_id);
261265
};
262266

263267
/* Zebra API message flag. */
@@ -680,6 +684,9 @@ bool zapi_ipset_entry_notify_decode(struct stream *s,
680684
uint32_t *unique,
681685
char *ipset_name,
682686
enum zapi_ipset_entry_notify_owner *note);
687+
bool zapi_iptable_notify_decode(struct stream *s,
688+
uint32_t *unique,
689+
enum zapi_iptable_notify_owner *note);
683690

684691
extern struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh);
685692
extern bool zapi_nexthop_update_decode(struct stream *s,

0 commit comments

Comments
 (0)