]> git.proxmox.com Git - mirror_frr.git/blobdiff - pbrd/pbr_zebra.c
Merge pull request #2992 from opensourcerouting/large_as_path_fix
[mirror_frr.git] / pbrd / pbr_zebra.c
index a1a2d34ac1d8499d64e2f4604fdce407b44979fa..25d64238bfd3b6ced06a290e6795e8bad96d93db 100644 (file)
@@ -45,17 +45,6 @@ DEFINE_MTYPE_STATIC(PBRD, PBR_INTERFACE, "PBR Interface")
 /* Zebra structure to hold current status. */
 struct zclient *zclient;
 
-static struct interface *zebra_interface_if_lookup(struct stream *s)
-{
-       char ifname_tmp[INTERFACE_NAMSIZ];
-
-       /* Read interface name. */
-       stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
-
-       /* And look it up. */
-       return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
-}
-
 struct pbr_interface *pbr_if_new(struct interface *ifp)
 {
        struct pbr_interface *pbr_ifp;
@@ -65,13 +54,8 @@ struct pbr_interface *pbr_if_new(struct interface *ifp)
 
        pbr_ifp = XCALLOC(MTYPE_PBR_INTERFACE, sizeof(*pbr_ifp));
 
-       if (!pbr_ifp) {
-               zlog_err("%s: PBR XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*pbr_ifp));
-               return 0;
-       }
-
-       return (pbr_ifp);
+       ifp->info = pbr_ifp;
+       return pbr_ifp;
 }
 
 /* Inteface addition message from zebra. */
@@ -85,12 +69,8 @@ static int interface_add(int command, struct zclient *zclient,
        if (!ifp)
                return 0;
 
-       if (!ifp->info) {
-               struct pbr_interface *pbr_ifp;
-
-               pbr_ifp = pbr_if_new(ifp);
-               ifp->info = pbr_ifp;
-       }
+       if (!ifp->info)
+               pbr_if_new(ifp);
 
        return 0;
 }
@@ -140,7 +120,7 @@ static int interface_state_up(int command, struct zclient *zclient,
                              zebra_size_t length, vrf_id_t vrf_id)
 {
 
-       zebra_interface_if_lookup(zclient->ibuf);
+       zebra_interface_state_read(zclient->ibuf, vrf_id);
 
        return 0;
 }
@@ -206,13 +186,16 @@ static int rule_notify_owner(int command, struct zclient *zclient,
        uint32_t seqno, priority, unique;
        enum zapi_rule_notify_owner note;
        struct pbr_map_sequence *pbrms;
+       struct pbr_map_interface *pmi;
        ifindex_t ifi;
+       uint64_t installed;
 
        if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique,
                                     &ifi, &note))
                return -1;
 
-       pbrms = pbrms_lookup_unique(unique, ifi);
+       pmi = NULL;
+       pbrms = pbrms_lookup_unique(unique, ifi, &pmi);
        if (!pbrms) {
                DEBUGD(&pbr_dbg_zebra,
                       "%s: Failure to lookup pbrms based upon %u",
@@ -220,18 +203,22 @@ static int rule_notify_owner(int command, struct zclient *zclient,
                return 0;
        }
 
+       installed = 1 << pmi->install_bit;
+
        switch (note) {
        case ZAPI_RULE_FAIL_INSTALL:
                DEBUGD(&pbr_dbg_zebra, "%s: Recieved RULE_FAIL_INSTALL",
                       __PRETTY_FUNCTION__);
-               pbrms->installed = false;
+               pbrms->installed &= ~installed;
                break;
        case ZAPI_RULE_INSTALLED:
-               pbrms->installed = true;
+               pbrms->installed |= installed;
                DEBUGD(&pbr_dbg_zebra, "%s: Recived RULE_INSTALLED",
                       __PRETTY_FUNCTION__);
                break;
+       case ZAPI_RULE_FAIL_REMOVE:
        case ZAPI_RULE_REMOVED:
+               pbrms->installed &= ~installed;
                DEBUGD(&pbr_dbg_zebra, "%s: Received RULE REMOVED",
                       __PRETTY_FUNCTION__);
                break;
@@ -487,6 +474,7 @@ static void pbr_encode_pbr_map_sequence(struct stream *s,
        stream_putw(s, 0);  /* src port */
        pbr_encode_pbr_map_sequence_prefix(s, pbrms->dst, family);
        stream_putw(s, 0);  /* dst port */
+       stream_putl(s, 0);  /* fwmark */
        if (pbrms->nhgrp_name)
                stream_putl(s, pbr_nht_get_table(pbrms->nhgrp_name));
        else if (pbrms->nhg)
@@ -499,9 +487,23 @@ void pbr_send_pbr_map(struct pbr_map_sequence *pbrms,
 {
        struct pbr_map *pbrm = pbrms->parent;
        struct stream *s;
+       uint64_t is_installed = (uint64_t)1 << pmi->install_bit;
+
+       is_installed &= pbrms->installed;
 
-       DEBUGD(&pbr_dbg_zebra, "%s: for %s %d", __PRETTY_FUNCTION__, pbrm->name,
-              install);
+       DEBUGD(&pbr_dbg_zebra, "%s: for %s %d(%" PRIu64 ")",
+              __PRETTY_FUNCTION__, pbrm->name, install, is_installed);
+
+       /*
+        * If we are installed and asked to do so again
+        * just return.  If we are not installed and asked
+        * and asked to delete just return;
+        */
+       if (install && is_installed)
+               return;
+
+       if (!install && !is_installed)
+               return;
 
        s = zclient->obuf;
        stream_reset(s);