* 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;
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)) {
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);
* 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);
}
/*
* 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);
}
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];
/* 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));
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);
}
/*
rule = (struct zebra_pbr_rule *)arg;
- kernel_del_pbr_rule(rule, NULL);
+ kernel_del_pbr_rule(rule);
XFREE(MTYPE_TMP, rule);
}
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);
}
if (!prefix_same(&r1->filter.dst_ip, &r2->filter.dst_ip))
return 0;
+ if (r1->ifp != r2->ifp)
+ return 0;
+
return 1;
}
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);
* 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)
{
}
/*
* 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;
}
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.
* 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.
* 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);
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;
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;
}
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: