]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: flowspec pbr entries listed on the bgp information entry
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 28 Jun 2018 15:26:22 +0000 (17:26 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 20 Aug 2018 16:33:38 +0000 (18:33 +0200)
Because one flowspec entry can create 1-N bgp pbr entries, the list is
now updated and visible. Also, because the bgp_extra structure is used,
this list is flushed when the bgp_extra structure is deleted.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_flowspec_vty.c
bgpd/bgp_pbr.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_zebra.c

index 90acd8fcb16f48beb0f07ac2436dae0eacd5c4d2..94695c6f6b677404a3808b51b3d18676963483cb 100644 (file)
@@ -332,16 +332,32 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
                struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
 
                if (extra->bgp_fs_pbr) {
+                       struct listnode *node;
                        struct bgp_pbr_match_entry *bpme;
                        struct bgp_pbr_match *bpm;
+                       int unit = 0;
+                       struct list *list_bpm;
 
-                       bpme = (struct bgp_pbr_match_entry *)extra->bgp_fs_pbr;
-                       bpm = bpme->backpointer;
-                       vty_out(vty, "\tinstalled in PBR");
-                       if (bpm)
-                               vty_out(vty, " (%s)\n", bpm->ipset_name);
-                       else
-                               vty_out(vty, "\n");
+                       list_bpm = list_new();
+                       if (listcount(extra->bgp_fs_pbr))
+                               vty_out(vty, "\tinstalled in PBR");
+                       for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_pbr,
+                                                 node, bpme)) {
+                               bpm = bpme->backpointer;
+                               if (listnode_lookup(list_bpm, bpm))
+                                       continue;
+                               listnode_add(list_bpm, bpm);
+                               if (unit == 0)
+                                       vty_out(vty, " (");
+                               else
+                                       vty_out(vty, ", ");
+                               vty_out(vty, "%s", bpm->ipset_name);
+                               unit++;
+                       }
+                       if (unit)
+                               vty_out(vty, ")");
+                       vty_out(vty, "\n");
+                       list_delete_all_node(list_bpm);
                } else
                        vty_out(vty, "\tnot installed in PBR\n");
        }
index 45ec21631c0f2fcb6113ed1f273b52b4d4b614ef..f2bd19207c0062f4c63ee07f72027487b35328c1 100644 (file)
@@ -1225,7 +1225,8 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
                        /* unlink bgp_info to bpme */
                        bgp_info = (struct bgp_info *)bpme->bgp_info;
                        extra = bgp_info_extra_get(bgp_info);
-                       extra->bgp_fs_pbr = NULL;
+                       if (extra->bgp_fs_pbr)
+                               listnode_delete(extra->bgp_fs_pbr, bpme);
                        bpme->bgp_info = NULL;
                }
        }
@@ -1597,6 +1598,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
        struct bgp_pbr_range_port *src_port;
        struct bgp_pbr_range_port *dst_port;
        struct bgp_pbr_range_port *pkt_len;
+       bool bpme_found = false;
 
        if (!bpf)
                return;
@@ -1817,8 +1819,21 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                bpme->install_in_progress = false;
                /* link bgp info to bpme */
                bpme->bgp_info = (void *)binfo;
-       }
+       } else
+               bpme_found = true;
 
+       /* already installed */
+       if (bpme_found && bpme) {
+               struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
+
+               if (extra && extra->bgp_fs_pbr &&
+                   listnode_lookup(extra->bgp_fs_pbr, bpme)) {
+                       if (BGP_DEBUG(pbr, PBR_ERROR))
+                               zlog_err("%s: entry %p/%p already installed in bgp pbr",
+                                        __func__, binfo, bpme);
+                       return;
+               }
+       }
        /* BGP FS: append entry to zebra
         * - policies are not routing entries and as such
         * route replace semantics don't necessarily follow
@@ -2195,7 +2210,6 @@ void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
                         bool nlri_update)
 {
        struct bgp_pbr_entry_main api;
-       struct bgp_info_extra *extra = bgp_info_extra_get(info);
 
        if (afi == AFI_IP6)
                return; /* IPv6 not supported */
@@ -2212,13 +2226,6 @@ void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
                                 __func__);
                return;
        }
-       /* already installed */
-       if (nlri_update && extra->bgp_fs_pbr) {
-               if (BGP_DEBUG(pbr, PBR_ERROR))
-                       zlog_err("%s: entry %p already installed in bgp pbr",
-                                __func__, info);
-               return;
-       }
 
        if (bgp_pbr_build_and_validate_entry(p, info, &api) < 0) {
                if (BGP_DEBUG(pbr, PBR_ERROR))
index dfca3231b7b59307a734c86c99ee39fe251c2592..bef492b46a6fed556adddfa3e4e51e2732cfab47 100644 (file)
@@ -180,6 +180,10 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra)
 
                (*extra)->damp_info = NULL;
 
+               if ((*extra)->bgp_fs_pbr)
+                       list_delete_all_node((*extra)->bgp_fs_pbr);
+               (*extra)->bgp_fs_pbr = NULL;
+
                XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
 
                *extra = NULL;
index 72923901b837cca1a3ea4f73a9d6b6871c0f9625..dfef9a8f79158c20f27cca79f92c59798b9cd018 100644 (file)
@@ -147,7 +147,7 @@ struct bgp_info_extra {
         */
        struct prefix nexthop_orig;
        /* presence of FS pbr entry */
-       void *bgp_fs_pbr;
+       struct list *bgp_fs_pbr;
 };
 
 struct bgp_info {
index 87c9036147674f2a8ba6bebae046306133e052fe..cba68380eb1334f08d8cbd87512035ffd66fbc63 100644 (file)
@@ -2088,7 +2088,9 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
                        /* 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;
+                       if (extra->bgp_fs_pbr == NULL)
+                               extra->bgp_fs_pbr = list_new();
+                       listnode_add(extra->bgp_fs_pbr, bgp_pbime);
                }
                break;
        case ZAPI_IPSET_ENTRY_FAIL_REMOVE: