diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/linklist.c | 22 | ||||
| -rw-r--r-- | lib/pbr.h | 29 | ||||
| -rw-r--r-- | lib/stream.c | 13 | ||||
| -rw-r--r-- | lib/stream.h | 3 | ||||
| -rw-r--r-- | lib/vrf.c | 39 | ||||
| -rw-r--r-- | lib/vty.c | 16 | ||||
| -rw-r--r-- | lib/workqueue.c | 3 |
7 files changed, 95 insertions, 30 deletions
diff --git a/lib/linklist.c b/lib/linklist.c index 2cfa3e7482..86649dd495 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -186,26 +186,10 @@ void listnode_move_to_tail(struct list *l, struct listnode *n) void listnode_delete(struct list *list, void *val) { - struct listnode *node; + struct listnode *node = listnode_lookup(list, val); - assert(list); - for (node = list->head; node; node = node->next) { - if (node->data == val) { - if (node->prev) - node->prev->next = node->next; - else - list->head = node->next; - - if (node->next) - node->next->prev = node->prev; - else - list->tail = node->prev; - - list->count--; - listnode_free(node); - return; - } - } + if (node) + list_delete_node(list, node); } void *listnode_head(struct list *list) @@ -89,6 +89,35 @@ struct pbr_rule { uint32_t ifindex; }; +/* TCP flags value shared + * those are values of byte 13 of TCP header + * as mentioned in rfc793 + */ +#define TCP_HEADER_FIN (0x01) +#define TCP_HEADER_SYN (0x02) +#define TCP_HEADER_RST (0x04) +#define TCP_HEADER_PSH (0x08) +#define TCP_HEADER_ACK (0x10) +#define TCP_HEADER_URG (0x20) +#define TCP_HEADER_ALL_FLAGS (TCP_HEADER_FIN | TCP_HEADER_SYN \ + | TCP_HEADER_RST | TCP_HEADER_PSH \ + | TCP_HEADER_ACK | TCP_HEADER_URG) + +/* Pbr IPTable defines + * those are common flags shared between BGP and Zebra + */ +#define MATCH_IP_SRC_SET (1 << 0) +#define MATCH_IP_DST_SET (1 << 1) +#define MATCH_PORT_SRC_SET (1 << 2) +#define MATCH_PORT_DST_SET (1 << 3) +#define MATCH_PORT_SRC_RANGE_SET (1 << 4) +#define MATCH_PORT_DST_RANGE_SET (1 << 5) +#define MATCH_DSCP_SET (1 << 6) +#define MATCH_DSCP_INVERSE_SET (1 << 7) +#define MATCH_PKT_LEN_INVERSE_SET (1 << 8) +#define MATCH_FRAGMENT_INVERSE_SET (1 << 9) +#define MATCH_ICMP_SET (1 << 10) + extern int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule); diff --git a/lib/stream.c b/lib/stream.c index aba4c20166..a172eedc99 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -1109,6 +1109,10 @@ struct stream_fifo *stream_fifo_new(void) /* Add new stream to fifo. */ void stream_fifo_push(struct stream_fifo *fifo, struct stream *s) { +#if defined DEV_BUILD + size_t max, curmax; +#endif + if (fifo->tail) fifo->tail->next = s; else @@ -1116,8 +1120,15 @@ void stream_fifo_push(struct stream_fifo *fifo, struct stream *s) fifo->tail = s; fifo->tail->next = NULL; - +#if !defined DEV_BUILD atomic_fetch_add_explicit(&fifo->count, 1, memory_order_release); +#else + max = atomic_fetch_add_explicit(&fifo->count, 1, memory_order_release); + curmax = atomic_load_explicit(&fifo->max_count, memory_order_relaxed); + if (max > curmax) + atomic_store_explicit(&fifo->max_count, max, + memory_order_relaxed); +#endif } void stream_fifo_push_safe(struct stream_fifo *fifo, struct stream *s) diff --git a/lib/stream.h b/lib/stream.h index e5d325e43e..11af85c663 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -115,6 +115,9 @@ struct stream_fifo { /* number of streams in this fifo */ _Atomic size_t count; +#if defined DEV_BUILD + _Atomic size_t max_count; +#endif struct stream *head; struct stream *tail; @@ -121,10 +121,10 @@ int vrf_switch_to_netns(vrf_id_t vrf_id) /* VRF is default VRF. silently ignore */ if (!vrf || vrf->vrf_id == VRF_DEFAULT) - return 0; + return 1; /* 1 = default */ /* VRF has no NETNS backend. silently ignore */ if (vrf->data.l.netns_name[0] == '\0') - return 0; + return 2; /* 2 = no netns */ name = ns_netns_pathname(NULL, vrf->data.l.netns_name); if (debug_vrf) zlog_debug("VRF_SWITCH: %s(%u)", name, vrf->vrf_id); @@ -505,6 +505,35 @@ void vrf_terminate(void) } } +static int vrf_default_accepts_vrf(int type) +{ + const char *fname = NULL; + char buf[32] = {0x0}; + int ret = 0; + FILE *fd = NULL; + + /* + * TCP & UDP services running in the default VRF context (ie., not bound + * to any VRF device) can work across all VRF domains by enabling the + * tcp_l3mdev_accept and udp_l3mdev_accept sysctl options: + * sysctl -w net.ipv4.tcp_l3mdev_accept=1 + * sysctl -w net.ipv4.udp_l3mdev_accept=1 + */ + if (type == SOCK_STREAM) + fname = "/proc/sys/net/ipv4/tcp_l3mdev_accept"; + else if (type == SOCK_DGRAM) + fname = "/proc/sys/net/ipv4/udp_l3mdev_accept"; + else + return ret; + fd = fopen(fname, "r"); + if (fd == NULL) + return ret; + fgets(buf, 32, fd); + ret = atoi(buf); + fclose(fd); + return ret; +} + /* Create a socket for the VRF. */ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id, char *interfacename) @@ -515,6 +544,12 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id, if (ret < 0) zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id, safe_strerror(errno)); + if (ret > 0 && interfacename && vrf_default_accepts_vrf(type)) { + zlog_err("VRF socket not used since net.ipv4.%s_l3mdev_accept != 0", + (type == SOCK_STREAM ? "tcp" : "udp")); + errno = EEXIST; /* not sure if this is the best error... */ + return -2; + } ret = socket(domain, type, protocol); save_errno = errno; ret2 = vrf_switchback_to_initial(); @@ -479,6 +479,8 @@ static int vty_command(struct vty *vty, char *buf) const char *protocolname; char *cp = NULL; + assert(vty); + /* * Log non empty command lines */ @@ -496,13 +498,13 @@ static int vty_command(struct vty *vty, char *buf) /* format the base vty info */ snprintf(vty_str, sizeof(vty_str), "vty[??]@%s", vty->address); - if (vty) - for (i = 0; i < vector_active(vtyvec); i++) - if (vty == vector_slot(vtyvec, i)) { - snprintf(vty_str, sizeof(vty_str), - "vty[%d]@%s", i, vty->address); - break; - } + + for (i = 0; i < vector_active(vtyvec); i++) + if (vty == vector_slot(vtyvec, i)) { + snprintf(vty_str, sizeof(vty_str), "vty[%d]@%s", + i, vty->address); + break; + } /* format the prompt */ snprintf(prompt_str, sizeof(prompt_str), cmd_prompt(vty->node), diff --git a/lib/workqueue.c b/lib/workqueue.c index 1af51c06c1..39dd142afb 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -245,10 +245,11 @@ int work_queue_run(struct thread *thread) char yielded = 0; wq = THREAD_ARG(thread); - wq->thread = NULL; assert(wq); + wq->thread = NULL; + /* calculate cycle granularity: * list iteration == 1 run * listnode processing == 1 cycle |
