]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: Make the ifp part of the rule structure
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 23 Feb 2018 18:45:36 +0000 (13:45 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 9 Mar 2018 16:07:41 +0000 (11:07 -0500)
Every place we need to pass around the rule structure
we need to pass around the ifp as well.  Move it into
the structure.  This will also allow us to notify up
to higher level protocols that this worked properly
or not better too.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/rule_netlink.c
zebra/zebra_pbr.c
zebra/zebra_pbr.h
zebra/zserv.c

index c64d9f6ab2d8c7cde50d6406af77bc84362ef0b5..2122f9f5fa12f308bab4b219eec1252f2b32b74a 100644 (file)
@@ -51,8 +51,7 @@
  * Form netlink message and ship it. Currently, notify status after
  * waiting for netlink status.
  */
-static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
-                              struct interface *ifp)
+static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule)
 {
        int family;
        int bytelen;
@@ -85,9 +84,9 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
        addattr32(&req.n, sizeof(req), FRA_PRIORITY, rule->priority);
 
        /* interface on which applied */
-       if (ifp)
-               addattr_l(&req.n, sizeof(req), FRA_IFNAME, ifp->name,
-                         strlen(ifp->name) + 1);
+       if (rule->ifp)
+               addattr_l(&req.n, sizeof(req), FRA_IFNAME, rule->ifp->name,
+                         strlen(rule->ifp->name) + 1);
 
        /* source IP, if specified */
        if (IS_RULE_FILTERING_ON_SRC_IP(rule)) {
@@ -115,8 +114,8 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
                zlog_debug(
                        "Tx %s family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
                        nl_msg_type_to_str(cmd), nl_family_to_str(family),
-                       ifp ? ifp->name : "Unknown", ifp ? ifp->ifindex : 0,
-                       rule->priority,
+                       rule->ifp ? rule->ifp->name : "Unknown",
+                       rule->ifp ? rule->ifp->ifindex : 0, rule->priority,
                        prefix2str(&rule->filter.src_ip, buf1, sizeof(buf1)),
                        prefix2str(&rule->filter.dst_ip, buf2, sizeof(buf2)),
                        rule->action.table);
@@ -138,12 +137,12 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
  * goes in the rule to denote relative ordering; it may or may not be the
  * same as the rule's user-defined sequence number.
  */
-void kernel_add_pbr_rule(struct zebra_pbr_rule *rule, struct interface *ifp)
+void kernel_add_pbr_rule(struct zebra_pbr_rule *rule)
 {
        int ret = 0;
 
-       ret = netlink_rule_update(RTM_NEWRULE, rule, ifp);
-       kernel_pbr_rule_add_del_status(rule, ifp,
+       ret = netlink_rule_update(RTM_NEWRULE, rule);
+       kernel_pbr_rule_add_del_status(rule,
                                       (!ret) ? SOUTHBOUND_INSTALL_SUCCESS
                                              : SOUTHBOUND_INSTALL_FAILURE);
 }
@@ -151,12 +150,12 @@ void kernel_add_pbr_rule(struct zebra_pbr_rule *rule, struct interface *ifp)
 /*
  * Uninstall specified rule for a specific interface.
  */
-void kernel_del_pbr_rule(struct zebra_pbr_rule *rule, struct interface *ifp)
+void kernel_del_pbr_rule(struct zebra_pbr_rule *rule)
 {
        int ret = 0;
 
-       ret = netlink_rule_update(RTM_DELRULE, rule, ifp);
-       kernel_pbr_rule_add_del_status(rule, ifp,
+       ret = netlink_rule_update(RTM_DELRULE, rule);
+       kernel_pbr_rule_add_del_status(rule,
                                       (!ret) ? SOUTHBOUND_DELETE_SUCCESS
                                              : SOUTHBOUND_DELETE_FAILURE);
 }
@@ -176,7 +175,6 @@ int netlink_rule_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
        struct rtattr *tb[FRA_MAX + 1];
        int len;
        char *ifname;
-       struct interface *ifp;
        struct zebra_pbr_rule rule;
        char buf1[PREFIX_STRLEN];
        char buf2[PREFIX_STRLEN];
@@ -209,8 +207,8 @@ int netlink_rule_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
        /* If we don't know the interface, we don't care. */
        ifname = (char *)RTA_DATA(tb[FRA_IFNAME]);
        zns = zebra_ns_lookup(ns_id);
-       ifp = if_lookup_by_name_per_ns(zns, ifname);
-       if (!ifp)
+       rule.ifp = if_lookup_by_name_per_ns(zns, ifname);
+       if (!rule.ifp)
                return 0;
 
        memset(&rule, 0, sizeof(rule));
@@ -248,13 +246,13 @@ int netlink_rule_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
                zlog_debug(
                        "Rx %s family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
                        nl_msg_type_to_str(h->nlmsg_type),
-                       nl_family_to_str(frh->family), ifp->name, ifp->ifindex,
-                       rule.priority,
+                       nl_family_to_str(frh->family), rule.ifp->name,
+                       rule.ifp->ifindex, rule.priority,
                        prefix2str(&rule.filter.src_ip, buf1, sizeof(buf1)),
                        prefix2str(&rule.filter.dst_ip, buf2, sizeof(buf2)),
                        rule.action.table);
 
-       return kernel_pbr_rule_del(&rule, ifp);
+       return kernel_pbr_rule_del(&rule);
 }
 
 /*
index 3f8655552b3997359f38751526a387688688644b..0096da942eb07f3928a693fae343d7a58e0ba861 100644 (file)
@@ -40,7 +40,7 @@ void zebra_pbr_rules_free(void *arg)
 
        rule = (struct zebra_pbr_rule *)arg;
 
-       kernel_del_pbr_rule(rule, NULL);
+       kernel_del_pbr_rule(rule);
        XFREE(MTYPE_TMP, rule);
 }
 
@@ -52,6 +52,11 @@ uint32_t zebra_pbr_rules_hash_key(void *arg)
        rule = (struct zebra_pbr_rule *)arg;
        key = jhash_3words(rule->seq, rule->priority, rule->action.table,
                           prefix_hash_key(&rule->filter.src_ip));
+       if (rule->ifp)
+               key = jhash_1word(rule->ifp->ifindex, key);
+       else
+               key = jhash_1word(0, key);
+
        return jhash_3words(rule->filter.src_port, rule->filter.dst_port,
                            prefix_hash_key(&rule->filter.dst_ip), key);
 }
@@ -84,6 +89,9 @@ int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
        if (!prefix_same(&r1->filter.dst_ip, &r2->filter.dst_ip))
                return 0;
 
+       if (r1->ifp != r2->ifp)
+               return 0;
+
        return 1;
 }
 
@@ -101,20 +109,18 @@ static void *pbr_rule_alloc_intern(void *arg)
        return new;
 }
 
-void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
-                       struct interface *ifp)
+void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
 {
        (void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
-       kernel_add_pbr_rule(rule, ifp);
+       kernel_add_pbr_rule(rule);
 }
 
-void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
-                       struct interface *ifp)
+void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
 {
        struct zebra_pbr_rule *lookup;
 
        lookup = hash_lookup(zns->rules_hash, rule);
-       kernel_del_pbr_rule(rule, ifp);
+       kernel_del_pbr_rule(rule);
 
        if (lookup)
                XFREE(MTYPE_TMP, lookup);
@@ -127,7 +133,6 @@ void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
  * Handle success or failure of rule (un)install in the kernel.
  */
 void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
-                                   struct interface *ifp,
                                    enum southbound_results res)
 {
 }
@@ -135,7 +140,7 @@ void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
 /*
  * Handle rule delete notification from kernel.
  */
-int kernel_pbr_rule_del(struct zebra_pbr_rule *rule, struct interface *ifp)
+int kernel_pbr_rule_del(struct zebra_pbr_rule *rule)
 {
        return 0;
 }
index f5f139cbda3d9c9aa2eeaad7436dd7a34fc6418f..9983de4f221fc3f95273f2bd2a3c7112de11a12b 100644 (file)
@@ -86,14 +86,13 @@ struct zebra_pbr_action {
 struct zebra_pbr_rule {
        uint32_t seq;
        uint32_t priority;
+       struct interface *ifp;
        struct zebra_pbr_filter filter;
        struct zebra_pbr_action action;
 };
 
-void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
-                       struct interface *ifp);
-void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
-                       struct interface *ifp);
+void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule);
+void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule);
 
 /*
  * Install specified rule for a specific interface.
@@ -101,14 +100,12 @@ void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
  * forwarding plane may not coincide, hence the API requires a separate
  * rule priority - maps to preference/FRA_PRIORITY on Linux.
  */
-extern void kernel_add_pbr_rule(struct zebra_pbr_rule *rule,
-                               struct interface *ifp);
+extern void kernel_add_pbr_rule(struct zebra_pbr_rule *rule);
 
 /*
  * Uninstall specified rule for a specific interface.
  */
-extern void kernel_del_pbr_rule(struct zebra_pbr_rule *rule,
-                               struct interface *ifp);
+extern void kernel_del_pbr_rule(struct zebra_pbr_rule *rule);
 
 /*
  * Get to know existing PBR rules in the kernel - typically called at startup.
@@ -119,14 +116,12 @@ extern void kernel_read_pbr_rules(struct zebra_ns *zns);
  * Handle success or failure of rule (un)install in the kernel.
  */
 extern void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
-                                          struct interface *ifp,
                                           enum southbound_results res);
 
 /*
  * Handle rule delete notification from kernel.
  */
-extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule,
-                              struct interface *ifp);
+extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule);
 
 extern void zebra_pbr_rules_free(void *arg);
 extern uint32_t zebra_pbr_rules_hash_key(void *arg);
index a56b388ec9a3f25476f6d0051ece0be1d95fccc8..d05b058c7c33a8baccc3b677b781dd0224b2b697 100644 (file)
@@ -2592,7 +2592,6 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
                              uint16_t length, struct zebra_vrf *zvrf)
 {
        struct zebra_pbr_rule zpr;
-       struct interface *ifp;
        struct stream *s;
        uint32_t total, i;
        ifindex_t ifindex;
@@ -2618,8 +2617,8 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
                STREAM_GETL(s, zpr.action.table);
                STREAM_GETL(s, ifindex);
 
-               ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN);
-               if (!ifp) {
+               zpr.ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN);
+               if (!zpr.ifp) {
                        zlog_debug("FAiled to lookup ifindex: %u", ifindex);
                        return;
                }
@@ -2636,7 +2635,10 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
                if (zpr.filter.dst_port)
                        zpr.filter.filter_bm |= PBR_FILTER_DST_PORT;
 
-               zebra_pbr_add_rule(zvrf->zns, &zpr, ifp);
+               if (command == ZEBRA_RULE_ADD)
+                       zebra_pbr_add_rule(zvrf->zns, &zpr);
+               else
+                       zebra_pbr_del_rule(zvrf->zns, &zpr);
        }
 
 stream_failure: