From 95a9fe025a2052a05150a450f423f9731127294b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcin=20Matla=CC=A8g?= Date: Wed, 5 Jun 2019 22:56:11 +0200 Subject: [PATCH] pbrd: initial fwmark support for pbr matches #4460 Adds support to specify marks in pbr-map match clause. Marks should be provided as decimal (unsigned int). Currently supported on Linux only. Attempting to configure marks on other platform will result in: "pbr marks are not supported on this platform" Signed-off-by: Marcin Matlag Signed-off-by: Jafar Al-Gharaibeh --- pbrd/pbr_map.c | 10 +++++----- pbrd/pbr_map.h | 3 ++- pbrd/pbr_vty.c | 33 +++++++++++++++++++++++++++++++++ pbrd/pbr_zebra.c | 2 +- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c index 5e67990d5e..1a8461c6c1 100644 --- a/pbrd/pbr_map.c +++ b/pbrd/pbr_map.c @@ -316,7 +316,7 @@ struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno) pbrms->ruleno = pbr_nht_get_next_rule(seqno); pbrms->parent = pbrm; pbrms->reason = - PBR_MAP_INVALID_SRCDST | + PBR_MAP_INVALID_EMPTY | PBR_MAP_INVALID_NO_NEXTHOPS; QOBJ_REG(pbrms, pbr_map_sequence); @@ -350,10 +350,10 @@ pbr_map_sequence_check_nexthops_valid(struct pbr_map_sequence *pbrms) } } -static void pbr_map_sequence_check_src_dst_valid(struct pbr_map_sequence *pbrms) +static void pbr_map_sequence_check_not_empty(struct pbr_map_sequence *pbrms) { - if (!pbrms->src && !pbrms->dst) - pbrms->reason |= PBR_MAP_INVALID_SRCDST; + if (!pbrms->src && !pbrms->dst && !pbrms->mark) + pbrms->reason |= PBR_MAP_INVALID_EMPTY; } /* @@ -364,7 +364,7 @@ static void pbr_map_sequence_check_valid(struct pbr_map_sequence *pbrms) { pbr_map_sequence_check_nexthops_valid(pbrms); - pbr_map_sequence_check_src_dst_valid(pbrms); + pbr_map_sequence_check_not_empty(pbrms); } static bool pbr_map_check_valid_internal(struct pbr_map *pbrm) diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h index 945f76bb2b..112acfe44e 100644 --- a/pbrd/pbr_map.h +++ b/pbrd/pbr_map.h @@ -87,6 +87,7 @@ struct pbr_map_sequence { */ struct prefix *src; struct prefix *dst; + uint32_t mark; /* * Family of the src/dst. Needed when deleting since we clear them @@ -126,7 +127,7 @@ struct pbr_map_sequence { #define PBR_MAP_INVALID_NEXTHOP (1 << 1) #define PBR_MAP_INVALID_NO_NEXTHOPS (1 << 2) #define PBR_MAP_INVALID_BOTH_NHANDGRP (1 << 3) -#define PBR_MAP_INVALID_SRCDST (1 << 4) +#define PBR_MAP_INVALID_EMPTY (1 << 4) uint64_t reason; QOBJ_FIELDS diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index 95f38563b1..5e7addc9d2 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -172,6 +172,33 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd, return CMD_SUCCESS; } +DEFPY(pbr_map_match_mark, pbr_map_match_mark_cmd, + "[no] match mark (1-4294967295)$mark", + NO_STR + "Match the rest of the command\n" + "Choose the mark value to use\n" + "mark\n") +{ + struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); + +#ifndef GNU_LINUX + vty_out(vty, "pbr marks are not supported on this platform"); + return CMD_WARNING_CONFIG_FAILED; +#endif + + if (!no) { + if (pbrms->mark == (uint32_t) mark) + return CMD_SUCCESS; + pbrms->mark = (uint32_t) mark; + } else { + pbrms->mark = 0; + } + + pbr_map_check(pbrms); + + return CMD_SUCCESS; + } + DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd, "[no] set nexthop-group NHGNAME$name", NO_STR @@ -453,6 +480,8 @@ DEFPY (show_pbr_map, vty_out(vty, "\tDST Match: %s\n", prefix2str(pbrms->dst, buf, sizeof(buf))); + if (pbrms->mark) + vty_out(vty, "\tMARK Match: %u\n", pbrms->mark); if (pbrms->nhgrp_name) { vty_out(vty, @@ -632,6 +661,9 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty, vty_out(vty, " match dst-ip %s\n", prefix2str(pbrms->dst, buff, sizeof(buff))); + if (pbrms->mark) + vty_out(vty, " match mark %u\n", pbrms->mark); + if (pbrms->nhgrp_name) vty_out(vty, " set nexthop-group %s\n", pbrms->nhgrp_name); @@ -704,6 +736,7 @@ void pbr_vty_init(void) install_element(INTERFACE_NODE, &pbr_policy_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_mark_cmd); install_element(PBRMAP_NODE, &pbr_map_nexthop_group_cmd); install_element(PBRMAP_NODE, &pbr_map_nexthop_cmd); install_element(VIEW_NODE, &show_pbr_cmd); diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index 466a9a13ae..d74d0fcd23 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -526,7 +526,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 */ + stream_putl(s, pbrms->mark); if (pbrms->nhgrp_name) stream_putl(s, pbr_nht_get_table(pbrms->nhgrp_name)); else if (pbrms->nhg) -- 2.39.5