mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-30 01:16:39 +00:00
Merge pull request #9007 from donaldsharp/pbr_stuff
add ability to match on proto to pbr
This commit is contained in:
commit
213d980ff9
@ -2576,6 +2576,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
|
|||||||
stream_putl(s, pbr->unique);
|
stream_putl(s, pbr->unique);
|
||||||
else
|
else
|
||||||
stream_putl(s, pbra->unique);
|
stream_putl(s, pbra->unique);
|
||||||
|
stream_putc(s, 0); /* ip protocol being used */
|
||||||
if (pbr && pbr->flags & MATCH_IP_SRC_SET)
|
if (pbr && pbr->flags & MATCH_IP_SRC_SET)
|
||||||
memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
|
memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
|
||||||
else {
|
else {
|
||||||
|
@ -117,6 +117,21 @@ end destination.
|
|||||||
both v4 and v6 prefixes. This command is used in conjunction of the
|
both v4 and v6 prefixes. This command is used in conjunction of the
|
||||||
:clicmd:`match src-ip PREFIX` command for matching.
|
:clicmd:`match src-ip PREFIX` command for matching.
|
||||||
|
|
||||||
|
.. clicmd:: match src-port (1-65535)
|
||||||
|
|
||||||
|
When a incoming packet matches the source port specified, take the
|
||||||
|
packet and forward according to the nexthops specified.
|
||||||
|
|
||||||
|
.. clicmd:: match dst-port (1-65535)
|
||||||
|
|
||||||
|
When a incoming packet matches the destination port specified, take the
|
||||||
|
packet and forward according to the nexthops specified.
|
||||||
|
|
||||||
|
.. clicmd:: match ip-protocol [tcp|udp]
|
||||||
|
|
||||||
|
When a incoming packet matches the specified ip protocol, take the
|
||||||
|
packet and forward according to the nexthops specified.
|
||||||
|
|
||||||
.. clicmd:: match mark (1-4294967295)
|
.. clicmd:: match mark (1-4294967295)
|
||||||
|
|
||||||
Select the mark to match. This is a linux only command and if attempted
|
Select the mark to match. This is a linux only command and if attempted
|
||||||
|
@ -49,7 +49,8 @@ struct pbr_filter {
|
|||||||
#define PBR_FILTER_PROTO (1 << 5)
|
#define PBR_FILTER_PROTO (1 << 5)
|
||||||
#define PBR_FILTER_SRC_PORT_RANGE (1 << 6)
|
#define PBR_FILTER_SRC_PORT_RANGE (1 << 6)
|
||||||
#define PBR_FILTER_DST_PORT_RANGE (1 << 7)
|
#define PBR_FILTER_DST_PORT_RANGE (1 << 7)
|
||||||
#define PBR_FILTER_DSFIELD (1 << 8)
|
#define PBR_FILTER_DSFIELD (1 << 8)
|
||||||
|
#define PBR_FILTER_IP_PROTOCOL (1 << 9)
|
||||||
|
|
||||||
#define PBR_DSFIELD_DSCP (0xfc) /* Upper 6 bits of DS field: DSCP */
|
#define PBR_DSFIELD_DSCP (0xfc) /* Upper 6 bits of DS field: DSCP */
|
||||||
#define PBR_DSFIELD_ECN (0x03) /* Lower 2 bits of DS field: BCN */
|
#define PBR_DSFIELD_ECN (0x03) /* Lower 2 bits of DS field: BCN */
|
||||||
@ -67,6 +68,9 @@ struct pbr_filter {
|
|||||||
|
|
||||||
/* Filter with fwmark */
|
/* Filter with fwmark */
|
||||||
uint32_t fwmark;
|
uint32_t fwmark;
|
||||||
|
|
||||||
|
/* Filter with the ip protocol */
|
||||||
|
uint8_t ip_proto;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -84,6 +84,17 @@ struct pbr_map_sequence {
|
|||||||
*/
|
*/
|
||||||
uint32_t ruleno;
|
uint32_t ruleno;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* src and dst ports
|
||||||
|
*/
|
||||||
|
uint16_t src_prt;
|
||||||
|
uint16_t dst_prt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ip protocol we want to match on
|
||||||
|
*/
|
||||||
|
uint8_t ip_proto;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our policy Catchers
|
* Our policy Catchers
|
||||||
*/
|
*/
|
||||||
|
@ -193,6 +193,76 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFPY(pbr_map_match_ip_proto, pbr_map_match_ip_proto_cmd,
|
||||||
|
"[no] match ip-protocol [tcp|udp]$ip_proto",
|
||||||
|
NO_STR
|
||||||
|
"Match the rest of the command\n"
|
||||||
|
"Choose an ip-protocol\n"
|
||||||
|
"Match on tcp flows\n"
|
||||||
|
"Match on udp flows\n")
|
||||||
|
{
|
||||||
|
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
|
||||||
|
struct protoent *p;
|
||||||
|
|
||||||
|
if (!no) {
|
||||||
|
p = getprotobyname(ip_proto);
|
||||||
|
if (!p) {
|
||||||
|
vty_out(vty, "Unable to convert %s to proto id\n",
|
||||||
|
ip_proto);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbrms->ip_proto = p->p_proto;
|
||||||
|
} else
|
||||||
|
pbrms->ip_proto = 0;
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY(pbr_map_match_src_port, pbr_map_match_src_port_cmd,
|
||||||
|
"[no] match src-port (1-65535)$port",
|
||||||
|
NO_STR
|
||||||
|
"Match the rest of the command\n"
|
||||||
|
"Choose the source port to use\n"
|
||||||
|
"The Source Port\n")
|
||||||
|
{
|
||||||
|
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
|
||||||
|
|
||||||
|
if (!no) {
|
||||||
|
if (pbrms->src_prt == port)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
else
|
||||||
|
pbrms->src_prt = port;
|
||||||
|
} else
|
||||||
|
pbrms->src_prt = 0;
|
||||||
|
|
||||||
|
pbr_map_check(pbrms, true);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY(pbr_map_match_dst_port, pbr_map_match_dst_port_cmd,
|
||||||
|
"[no] match dst-port (1-65535)$port",
|
||||||
|
NO_STR
|
||||||
|
"Match the rest of the command\n"
|
||||||
|
"Choose the destination port to use\n"
|
||||||
|
"The Destination Port\n")
|
||||||
|
{
|
||||||
|
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
|
||||||
|
|
||||||
|
if (!no) {
|
||||||
|
if (pbrms->dst_prt == port)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
else
|
||||||
|
pbrms->dst_prt = port;
|
||||||
|
} else
|
||||||
|
pbrms->dst_prt = 0;
|
||||||
|
|
||||||
|
pbr_map_check(pbrms, true);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFPY(pbr_map_match_dscp, pbr_map_match_dscp_cmd,
|
DEFPY(pbr_map_match_dscp, pbr_map_match_dscp_cmd,
|
||||||
"[no] match dscp DSCP$dscp",
|
"[no] match dscp DSCP$dscp",
|
||||||
NO_STR
|
NO_STR
|
||||||
@ -674,6 +744,13 @@ static void vty_show_pbrms(struct vty *vty,
|
|||||||
pbrms->installed ? "yes" : "no",
|
pbrms->installed ? "yes" : "no",
|
||||||
pbrms->reason ? rbuf : "Valid");
|
pbrms->reason ? rbuf : "Valid");
|
||||||
|
|
||||||
|
if (pbrms->ip_proto) {
|
||||||
|
struct protoent *p;
|
||||||
|
|
||||||
|
p = getprotobynumber(pbrms->ip_proto);
|
||||||
|
vty_out(vty, " IP Protocol Match: %s\n", p->p_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (pbrms->src)
|
if (pbrms->src)
|
||||||
vty_out(vty, " SRC Match: %pFX\n", pbrms->src);
|
vty_out(vty, " SRC Match: %pFX\n", pbrms->src);
|
||||||
if (pbrms->dst)
|
if (pbrms->dst)
|
||||||
@ -1079,6 +1156,18 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty,
|
|||||||
if (pbrms->dst)
|
if (pbrms->dst)
|
||||||
vty_out(vty, " match dst-ip %pFX\n", pbrms->dst);
|
vty_out(vty, " match dst-ip %pFX\n", pbrms->dst);
|
||||||
|
|
||||||
|
if (pbrms->src_prt)
|
||||||
|
vty_out(vty, " match src-port %u\n", pbrms->src_prt);
|
||||||
|
if (pbrms->dst_prt)
|
||||||
|
vty_out(vty, " match dst-port %u\n", pbrms->dst_prt);
|
||||||
|
|
||||||
|
if (pbrms->ip_proto) {
|
||||||
|
struct protoent *p;
|
||||||
|
|
||||||
|
p = getprotobynumber(pbrms->ip_proto);
|
||||||
|
vty_out(vty, " match ip-protocol %s\n", p->p_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (pbrms->dsfield & PBR_DSFIELD_DSCP)
|
if (pbrms->dsfield & PBR_DSFIELD_DSCP)
|
||||||
vty_out(vty, " match dscp %u\n",
|
vty_out(vty, " match dscp %u\n",
|
||||||
(pbrms->dsfield & PBR_DSFIELD_DSCP) >> 2);
|
(pbrms->dsfield & PBR_DSFIELD_DSCP) >> 2);
|
||||||
@ -1169,6 +1258,9 @@ void pbr_vty_init(void)
|
|||||||
install_element(CONFIG_NODE, &pbr_set_table_range_cmd);
|
install_element(CONFIG_NODE, &pbr_set_table_range_cmd);
|
||||||
install_element(CONFIG_NODE, &no_pbr_set_table_range_cmd);
|
install_element(CONFIG_NODE, &no_pbr_set_table_range_cmd);
|
||||||
install_element(INTERFACE_NODE, &pbr_policy_cmd);
|
install_element(INTERFACE_NODE, &pbr_policy_cmd);
|
||||||
|
install_element(PBRMAP_NODE, &pbr_map_match_ip_proto_cmd);
|
||||||
|
install_element(PBRMAP_NODE, &pbr_map_match_src_port_cmd);
|
||||||
|
install_element(PBRMAP_NODE, &pbr_map_match_dst_port_cmd);
|
||||||
install_element(PBRMAP_NODE, &pbr_map_match_src_cmd);
|
install_element(PBRMAP_NODE, &pbr_map_match_src_cmd);
|
||||||
install_element(PBRMAP_NODE, &pbr_map_match_dst_cmd);
|
install_element(PBRMAP_NODE, &pbr_map_match_dst_cmd);
|
||||||
install_element(PBRMAP_NODE, &pbr_map_match_dscp_cmd);
|
install_element(PBRMAP_NODE, &pbr_map_match_dscp_cmd);
|
||||||
|
@ -534,10 +534,11 @@ static void pbr_encode_pbr_map_sequence(struct stream *s,
|
|||||||
stream_putl(s, pbrms->seqno);
|
stream_putl(s, pbrms->seqno);
|
||||||
stream_putl(s, pbrms->ruleno);
|
stream_putl(s, pbrms->ruleno);
|
||||||
stream_putl(s, pbrms->unique);
|
stream_putl(s, pbrms->unique);
|
||||||
|
stream_putc(s, pbrms->ip_proto); /* The ip_proto */
|
||||||
pbr_encode_pbr_map_sequence_prefix(s, pbrms->src, family);
|
pbr_encode_pbr_map_sequence_prefix(s, pbrms->src, family);
|
||||||
stream_putw(s, 0); /* src port */
|
stream_putw(s, pbrms->src_prt);
|
||||||
pbr_encode_pbr_map_sequence_prefix(s, pbrms->dst, family);
|
pbr_encode_pbr_map_sequence_prefix(s, pbrms->dst, family);
|
||||||
stream_putw(s, 0); /* dst port */
|
stream_putw(s, pbrms->dst_prt);
|
||||||
stream_putc(s, pbrms->dsfield);
|
stream_putc(s, pbrms->dsfield);
|
||||||
stream_putl(s, pbrms->mark);
|
stream_putl(s, pbrms->mark);
|
||||||
|
|
||||||
|
@ -550,6 +550,12 @@ bool nl_attr_put(struct nlmsghdr *n, unsigned int maxlen, int type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nl_attr_put8(struct nlmsghdr *n, unsigned int maxlen, int type,
|
||||||
|
uint8_t data)
|
||||||
|
{
|
||||||
|
return nl_attr_put(n, maxlen, type, &data, sizeof(uint8_t));
|
||||||
|
}
|
||||||
|
|
||||||
bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,
|
bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,
|
||||||
uint16_t data)
|
uint16_t data)
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,8 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
extern bool nl_attr_put(struct nlmsghdr *n, unsigned int maxlen, int type,
|
extern bool nl_attr_put(struct nlmsghdr *n, unsigned int maxlen, int type,
|
||||||
const void *data, unsigned int alen);
|
const void *data, unsigned int alen);
|
||||||
|
extern bool nl_attr_put8(struct nlmsghdr *n, unsigned int maxlen, int type,
|
||||||
|
uint8_t data);
|
||||||
extern bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,
|
extern bool nl_attr_put16(struct nlmsghdr *n, unsigned int maxlen, int type,
|
||||||
uint16_t data);
|
uint16_t data);
|
||||||
extern bool nl_attr_put32(struct nlmsghdr *n, unsigned int maxlen, int type,
|
extern bool nl_attr_put32(struct nlmsghdr *n, unsigned int maxlen, int type,
|
||||||
|
@ -58,12 +58,11 @@
|
|||||||
* Returns -1 on failure, 0 when the msg doesn't fit entirely in the buffer
|
* Returns -1 on failure, 0 when the msg doesn't fit entirely in the buffer
|
||||||
* or the number of bytes written to buf.
|
* or the number of bytes written to buf.
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
static ssize_t netlink_rule_msg_encode(
|
||||||
netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
|
int cmd, const struct zebra_dplane_ctx *ctx, uint32_t filter_bm,
|
||||||
uint32_t filter_bm, uint32_t priority, uint32_t table,
|
uint32_t priority, uint32_t table, const struct prefix *src_ip,
|
||||||
const struct prefix *src_ip,
|
const struct prefix *dst_ip, uint32_t fwmark, uint8_t dsfield,
|
||||||
const struct prefix *dst_ip, uint32_t fwmark,
|
uint8_t ip_protocol, void *buf, size_t buflen)
|
||||||
uint8_t dsfield, void *buf, size_t buflen)
|
|
||||||
{
|
{
|
||||||
uint8_t protocol = RTPROT_ZEBRA;
|
uint8_t protocol = RTPROT_ZEBRA;
|
||||||
int family;
|
int family;
|
||||||
@ -136,6 +135,10 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
|
|||||||
if (filter_bm & PBR_FILTER_DSFIELD)
|
if (filter_bm & PBR_FILTER_DSFIELD)
|
||||||
req->frh.tos = dsfield;
|
req->frh.tos = dsfield;
|
||||||
|
|
||||||
|
/* protocol to match on */
|
||||||
|
if (filter_bm & PBR_FILTER_IP_PROTOCOL)
|
||||||
|
nl_attr_put8(&req->n, buflen, FRA_IP_PROTO, ip_protocol);
|
||||||
|
|
||||||
/* Route table to use to forward, if filter criteria matches. */
|
/* Route table to use to forward, if filter criteria matches. */
|
||||||
if (table < 256)
|
if (table < 256)
|
||||||
req->frh.table = table;
|
req->frh.table = table;
|
||||||
@ -168,7 +171,8 @@ static ssize_t netlink_rule_msg_encoder(struct zebra_dplane_ctx *ctx, void *buf,
|
|||||||
dplane_ctx_rule_get_table(ctx), dplane_ctx_rule_get_src_ip(ctx),
|
dplane_ctx_rule_get_table(ctx), dplane_ctx_rule_get_src_ip(ctx),
|
||||||
dplane_ctx_rule_get_dst_ip(ctx),
|
dplane_ctx_rule_get_dst_ip(ctx),
|
||||||
dplane_ctx_rule_get_fwmark(ctx),
|
dplane_ctx_rule_get_fwmark(ctx),
|
||||||
dplane_ctx_rule_get_dsfield(ctx), buf, buflen);
|
dplane_ctx_rule_get_dsfield(ctx),
|
||||||
|
dplane_ctx_rule_get_ipproto(ctx), buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t netlink_oldrule_msg_encoder(struct zebra_dplane_ctx *ctx,
|
static ssize_t netlink_oldrule_msg_encoder(struct zebra_dplane_ctx *ctx,
|
||||||
@ -181,7 +185,8 @@ static ssize_t netlink_oldrule_msg_encoder(struct zebra_dplane_ctx *ctx,
|
|||||||
dplane_ctx_rule_get_old_src_ip(ctx),
|
dplane_ctx_rule_get_old_src_ip(ctx),
|
||||||
dplane_ctx_rule_get_old_dst_ip(ctx),
|
dplane_ctx_rule_get_old_dst_ip(ctx),
|
||||||
dplane_ctx_rule_get_old_fwmark(ctx),
|
dplane_ctx_rule_get_old_fwmark(ctx),
|
||||||
dplane_ctx_rule_get_old_dsfield(ctx), buf, buflen);
|
dplane_ctx_rule_get_old_dsfield(ctx),
|
||||||
|
dplane_ctx_rule_get_old_ipproto(ctx), buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Public functions */
|
/* Public functions */
|
||||||
@ -236,6 +241,7 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
|||||||
char *ifname;
|
char *ifname;
|
||||||
struct zebra_pbr_rule rule = {};
|
struct zebra_pbr_rule rule = {};
|
||||||
uint8_t proto = 0;
|
uint8_t proto = 0;
|
||||||
|
uint8_t ip_proto = 0;
|
||||||
|
|
||||||
/* Basic validation followed by extracting attributes. */
|
/* Basic validation followed by extracting attributes. */
|
||||||
if (h->nlmsg_type != RTM_NEWRULE && h->nlmsg_type != RTM_DELRULE)
|
if (h->nlmsg_type != RTM_NEWRULE && h->nlmsg_type != RTM_DELRULE)
|
||||||
@ -312,6 +318,9 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
|||||||
if (tb[FRA_PROTOCOL])
|
if (tb[FRA_PROTOCOL])
|
||||||
proto = *(uint8_t *)RTA_DATA(tb[FRA_PROTOCOL]);
|
proto = *(uint8_t *)RTA_DATA(tb[FRA_PROTOCOL]);
|
||||||
|
|
||||||
|
if (tb[FRA_IP_PROTO])
|
||||||
|
ip_proto = *(uint8_t *)RTA_DATA(tb[FRA_IP_PROTO]);
|
||||||
|
|
||||||
ifname = (char *)RTA_DATA(tb[FRA_IFNAME]);
|
ifname = (char *)RTA_DATA(tb[FRA_IFNAME]);
|
||||||
strlcpy(rule.ifname, ifname, sizeof(rule.ifname));
|
strlcpy(rule.ifname, ifname, sizeof(rule.ifname));
|
||||||
|
|
||||||
@ -326,7 +335,7 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
|||||||
ret = dplane_pbr_rule_delete(&rule);
|
ret = dplane_pbr_rule_delete(&rule);
|
||||||
|
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: %s leftover rule: family %s IF %s Pref %u Src %pFX Dst %pFX Table %u",
|
"%s: %s leftover rule: family %s IF %s Pref %u Src %pFX Dst %pFX Table %u ip-proto: %u",
|
||||||
__func__,
|
__func__,
|
||||||
((ret == ZEBRA_DPLANE_REQUEST_FAILURE)
|
((ret == ZEBRA_DPLANE_REQUEST_FAILURE)
|
||||||
? "Failed to remove"
|
? "Failed to remove"
|
||||||
@ -334,7 +343,7 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
|||||||
nl_family_to_str(frh->family), rule.ifname,
|
nl_family_to_str(frh->family), rule.ifname,
|
||||||
rule.rule.priority, &rule.rule.filter.src_ip,
|
rule.rule.priority, &rule.rule.filter.src_ip,
|
||||||
&rule.rule.filter.dst_ip,
|
&rule.rule.filter.dst_ip,
|
||||||
rule.rule.action.table);
|
rule.rule.action.table, ip_proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TBD */
|
/* TBD */
|
||||||
@ -349,11 +358,12 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"Rx %s family %s IF %s Pref %u Src %pFX Dst %pFX Table %u",
|
"Rx %s family %s IF %s Pref %u Src %pFX Dst %pFX Table %u ip-proto: %u",
|
||||||
nl_msg_type_to_str(h->nlmsg_type),
|
nl_msg_type_to_str(h->nlmsg_type),
|
||||||
nl_family_to_str(frh->family), rule.ifname,
|
nl_family_to_str(frh->family), rule.ifname,
|
||||||
rule.rule.priority, &rule.rule.filter.src_ip,
|
rule.rule.priority, &rule.rule.filter.src_ip,
|
||||||
&rule.rule.filter.dst_ip, rule.rule.action.table);
|
&rule.rule.filter.dst_ip, rule.rule.action.table,
|
||||||
|
ip_proto);
|
||||||
|
|
||||||
return kernel_pbr_rule_del(&rule);
|
return kernel_pbr_rule_del(&rule);
|
||||||
}
|
}
|
||||||
|
@ -3131,6 +3131,7 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
|
|||||||
STREAM_GETL(s, zpr.rule.seq);
|
STREAM_GETL(s, zpr.rule.seq);
|
||||||
STREAM_GETL(s, zpr.rule.priority);
|
STREAM_GETL(s, zpr.rule.priority);
|
||||||
STREAM_GETL(s, zpr.rule.unique);
|
STREAM_GETL(s, zpr.rule.unique);
|
||||||
|
STREAM_GETC(s, zpr.rule.filter.ip_proto);
|
||||||
STREAM_GETC(s, zpr.rule.filter.src_ip.family);
|
STREAM_GETC(s, zpr.rule.filter.src_ip.family);
|
||||||
STREAM_GETC(s, zpr.rule.filter.src_ip.prefixlen);
|
STREAM_GETC(s, zpr.rule.filter.src_ip.prefixlen);
|
||||||
STREAM_GET(&zpr.rule.filter.src_ip.u.prefix, s,
|
STREAM_GET(&zpr.rule.filter.src_ip.u.prefix, s,
|
||||||
@ -3164,6 +3165,9 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
|
|||||||
if (zpr.rule.filter.dsfield)
|
if (zpr.rule.filter.dsfield)
|
||||||
zpr.rule.filter.filter_bm |= PBR_FILTER_DSFIELD;
|
zpr.rule.filter.filter_bm |= PBR_FILTER_DSFIELD;
|
||||||
|
|
||||||
|
if (zpr.rule.filter.ip_proto)
|
||||||
|
zpr.rule.filter.filter_bm |= PBR_FILTER_IP_PROTOCOL;
|
||||||
|
|
||||||
if (zpr.rule.filter.fwmark)
|
if (zpr.rule.filter.fwmark)
|
||||||
zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
|
zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
|
||||||
|
|
||||||
|
@ -259,6 +259,7 @@ struct dplane_ctx_rule {
|
|||||||
uint8_t dsfield;
|
uint8_t dsfield;
|
||||||
struct prefix src_ip;
|
struct prefix src_ip;
|
||||||
struct prefix dst_ip;
|
struct prefix dst_ip;
|
||||||
|
uint8_t ip_proto;
|
||||||
char ifname[INTERFACE_NAMSIZ + 1];
|
char ifname[INTERFACE_NAMSIZ + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1929,6 +1930,20 @@ uint32_t dplane_ctx_rule_get_old_fwmark(const struct zebra_dplane_ctx *ctx)
|
|||||||
return ctx->u.rule.old.fwmark;
|
return ctx->u.rule.old.fwmark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t dplane_ctx_rule_get_ipproto(const struct zebra_dplane_ctx *ctx)
|
||||||
|
{
|
||||||
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
|
||||||
|
return ctx->u.rule.new.ip_proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dplane_ctx_rule_get_old_ipproto(const struct zebra_dplane_ctx *ctx)
|
||||||
|
{
|
||||||
|
DPLANE_CTX_VALID(ctx);
|
||||||
|
|
||||||
|
return ctx->u.rule.old.ip_proto;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx)
|
uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx)
|
||||||
{
|
{
|
||||||
DPLANE_CTX_VALID(ctx);
|
DPLANE_CTX_VALID(ctx);
|
||||||
@ -2636,6 +2651,7 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule,
|
|||||||
dplane_rule->filter_bm = rule->rule.filter.filter_bm;
|
dplane_rule->filter_bm = rule->rule.filter.filter_bm;
|
||||||
dplane_rule->fwmark = rule->rule.filter.fwmark;
|
dplane_rule->fwmark = rule->rule.filter.fwmark;
|
||||||
dplane_rule->dsfield = rule->rule.filter.dsfield;
|
dplane_rule->dsfield = rule->rule.filter.dsfield;
|
||||||
|
dplane_rule->ip_proto = rule->rule.filter.ip_proto;
|
||||||
prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip);
|
prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip);
|
||||||
prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip);
|
prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip);
|
||||||
strlcpy(dplane_rule->ifname, rule->ifname, INTERFACE_NAMSIZ);
|
strlcpy(dplane_rule->ifname, rule->ifname, INTERFACE_NAMSIZ);
|
||||||
|
@ -493,6 +493,8 @@ uint32_t dplane_ctx_rule_get_fwmark(const struct zebra_dplane_ctx *ctx);
|
|||||||
uint32_t dplane_ctx_rule_get_old_fwmark(const struct zebra_dplane_ctx *ctx);
|
uint32_t dplane_ctx_rule_get_old_fwmark(const struct zebra_dplane_ctx *ctx);
|
||||||
uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx);
|
uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx);
|
||||||
uint8_t dplane_ctx_rule_get_old_dsfield(const struct zebra_dplane_ctx *ctx);
|
uint8_t dplane_ctx_rule_get_old_dsfield(const struct zebra_dplane_ctx *ctx);
|
||||||
|
uint8_t dplane_ctx_rule_get_ipproto(const struct zebra_dplane_ctx *ctx);
|
||||||
|
uint8_t dplane_ctx_rule_get_old_ipproto(const struct zebra_dplane_ctx *ctx);
|
||||||
const struct prefix *
|
const struct prefix *
|
||||||
dplane_ctx_rule_get_src_ip(const struct zebra_dplane_ctx *ctx);
|
dplane_ctx_rule_get_src_ip(const struct zebra_dplane_ctx *ctx);
|
||||||
const struct prefix *
|
const struct prefix *
|
||||||
|
@ -166,10 +166,8 @@ uint32_t zebra_pbr_rules_hash_key(const void *arg)
|
|||||||
rule->rule.action.table,
|
rule->rule.action.table,
|
||||||
prefix_hash_key(&rule->rule.filter.src_ip));
|
prefix_hash_key(&rule->rule.filter.src_ip));
|
||||||
|
|
||||||
if (rule->rule.filter.fwmark)
|
key = jhash_3words(rule->rule.filter.fwmark, rule->vrf_id,
|
||||||
key = jhash_2words(rule->rule.filter.fwmark, rule->vrf_id, key);
|
rule->rule.filter.ip_proto, key);
|
||||||
else
|
|
||||||
key = jhash_1word(rule->vrf_id, key);
|
|
||||||
|
|
||||||
key = jhash(rule->ifname, strlen(rule->ifname), key);
|
key = jhash(rule->ifname, strlen(rule->ifname), key);
|
||||||
|
|
||||||
@ -207,6 +205,9 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
|
|||||||
if (r1->rule.filter.fwmark != r2->rule.filter.fwmark)
|
if (r1->rule.filter.fwmark != r2->rule.filter.fwmark)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (r1->rule.filter.ip_proto != r2->rule.filter.ip_proto)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!prefix_same(&r1->rule.filter.src_ip, &r2->rule.filter.src_ip))
|
if (!prefix_same(&r1->rule.filter.src_ip, &r2->rule.filter.src_ip))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user