diff options
-rw-r--r-- | vnet/vnet/ip/ip4_source_and_port_range_check.c | 1177 | ||||
-rw-r--r-- | vnet/vnet/ip/ip_source_and_port_range_check.h | 49 |
2 files changed, 647 insertions, 579 deletions
diff --git a/vnet/vnet/ip/ip4_source_and_port_range_check.c b/vnet/vnet/ip/ip4_source_and_port_range_check.c index c36678c9860..f716ebdb1e1 100644 --- a/vnet/vnet/ip/ip4_source_and_port_range_check.c +++ b/vnet/vnet/ip/ip4_source_and_port_range_check.c @@ -22,20 +22,22 @@ vlib_node_registration_t ip4_source_port_and_range_check; _(CHECK_FAIL, "ip4 source and port range check bad packets") \ _(CHECK_OK, "ip4 source and port range check good packets") -typedef enum { +typedef enum +{ #define _(sym,str) IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_##sym, foreach_ip4_source_and_port_range_check_error #undef _ - IP4_SOURCE_AND_PORT_RANGE_CHECK_N_ERROR, + IP4_SOURCE_AND_PORT_RANGE_CHECK_N_ERROR, } ip4_source_and_port_range_check_error_t; -static char * ip4_source_and_port_range_check_error_strings[] = { +static char *ip4_source_and_port_range_check_error_strings[] = { #define _(sym,string) string, foreach_ip4_source_and_port_range_check_error #undef _ }; -typedef struct { +typedef struct +{ u32 pass; u32 bypass; u32 is_tcp; @@ -44,32 +46,33 @@ typedef struct { u32 fib_index; } ip4_source_and_port_range_check_trace_t; -static u8 * format_ip4_source_and_port_range_check_trace (u8 * s, va_list * va) +static u8 * +format_ip4_source_and_port_range_check_trace (u8 * s, va_list * va) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *); - ip4_source_and_port_range_check_trace_t * t = + ip4_source_and_port_range_check_trace_t *t = va_arg (*va, ip4_source_and_port_range_check_trace_t *); if (t->bypass) s = format (s, "PASS (bypass case)"); else s = format (s, "fib %d src ip %U %s dst port %d: %s", - t->fib_index, format_ip4_address, &t->src_addr, t->is_tcp ? "TCP" : "UDP", - (u32) t->dst_port, - (t->pass == 1) ? "PASS" : "FAIL"); + t->fib_index, format_ip4_address, &t->src_addr, + t->is_tcp ? "TCP" : "UDP", (u32) t->dst_port, + (t->pass == 1) ? "PASS" : "FAIL"); return s; } -typedef enum { +typedef enum +{ IP4_SOURCE_AND_PORT_RANGE_CHECK_NEXT_DROP, IP4_SOURCE_AND_PORT_RANGE_CHECK_N_NEXT, } ip4_source_and_port_range_check_next_t; -static inline u32 check_adj_port_range_x1 (ip_adjacency_t * adj, - u16 dst_port, - u32 next) +static inline u32 +check_adj_port_range_x1 (ip_adjacency_t * adj, u16 dst_port, u32 next) { protocol_port_range_t *range; u16x8vec_t key; @@ -78,58 +81,61 @@ static inline u32 check_adj_port_range_x1 (ip_adjacency_t * adj, u16x8vec_t sum, sum_equal_diff2; u16 sum_nonzero, sum_equal, winner_mask; int i; - u8 * rwh; + u8 *rwh; if (adj->lookup_next_index != IP_LOOKUP_NEXT_ICMP_ERROR || dst_port == 0) return IP4_SOURCE_AND_PORT_RANGE_CHECK_NEXT_DROP; - rwh = (u8 *)(&adj->rewrite_header); - range = (protocol_port_range_t *)rwh; + rwh = (u8 *) (&adj->rewrite_header); + range = (protocol_port_range_t *) rwh; /* Make the obvious screw-case work. A variant also works w/ no MMX */ - if (PREDICT_FALSE(dst_port == 65535)) + if (PREDICT_FALSE (dst_port == 65535)) { int j; - for (i = 0; i < VLIB_BUFFER_PRE_DATA_SIZE / sizeof(protocol_port_range_t); i++) - { - for (j = 0; j < 8; j++) - if (range->low.as_u16x8[j] == 65535) - return next; - range++; - } + for (i = 0; + i < VLIB_BUFFER_PRE_DATA_SIZE / sizeof (protocol_port_range_t); + i++) + { + for (j = 0; j < 8; j++) + if (range->low.as_u16[j] == 65535) + return next; + range++; + } return IP4_SOURCE_AND_PORT_RANGE_CHECK_NEXT_DROP; } key.as_u16x8 = u16x8_splat (dst_port); - for (i = 0; i < VLIB_BUFFER_PRE_DATA_SIZE / sizeof(protocol_port_range_t); i++) + for (i = 0; i < VLIB_BUFFER_PRE_DATA_SIZE / sizeof (protocol_port_range_t); + i++) { diff1.as_u16x8 = u16x8_sub_saturate (range->low.as_u16x8, key.as_u16x8); diff2.as_u16x8 = u16x8_sub_saturate (range->hi.as_u16x8, key.as_u16x8); sum.as_u16x8 = u16x8_add (diff1.as_u16x8, diff2.as_u16x8); - sum_equal_diff2.as_u16x8 = u16x8_is_equal (sum.as_u16x8, diff2.as_u16x8); + sum_equal_diff2.as_u16x8 = + u16x8_is_equal (sum.as_u16x8, diff2.as_u16x8); sum_nonzero = ~u16x8_zero_byte_mask (sum.as_u16x8); sum_equal = ~u16x8_zero_byte_mask (sum_equal_diff2.as_u16x8); winner_mask = sum_nonzero & sum_equal; if (winner_mask) - return next; + return next; range++; } return IP4_SOURCE_AND_PORT_RANGE_CHECK_NEXT_DROP; } always_inline uword -ip4_source_and_port_range_check_inline -(vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame) + ip4_source_and_port_range_check_inline + (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - ip_config_main_t * cm = &lm->rx_config_mains[VNET_UNICAST]; - u32 n_left_from, * from, * to_next; + ip4_main_t *im = &ip4_main; + ip_lookup_main_t *lm = &im->lookup_main; + ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST]; + u32 n_left_from, *from, *to_next; u32 next_index; - vlib_node_runtime_t * error_node = node; + vlib_node_runtime_t *error_node = node; u32 good_packets = 0; int i; @@ -141,328 +147,346 @@ ip4_source_and_port_range_check_inline { u32 n_left_to_next; - vlib_get_next_frame (vm, node, next_index, - to_next, n_left_to_next); + vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from >= 4 && n_left_to_next >= 2) - { - vlib_buffer_t * b0, * b1; - ip4_header_t * ip0, * ip1; - ip4_fib_mtrie_t * mtrie0, * mtrie1; - ip4_fib_mtrie_leaf_t leaf0, leaf1; - ip_source_and_port_range_check_config_t * c0, * c1; - ip_adjacency_t * adj0 = 0, * adj1 = 0; - u32 bi0, next0, adj_index0, pass0, save_next0, fib_index0; - u32 bi1, next1, adj_index1, pass1, save_next1, fib_index1; - udp_header_t * udp0, * udp1; - - /* Prefetch next iteration. */ - { - vlib_buffer_t * p2, * p3; - - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); - - vlib_prefetch_buffer_header (p2, LOAD); - vlib_prefetch_buffer_header (p3, LOAD); + { + vlib_buffer_t *b0, *b1; + ip4_header_t *ip0, *ip1; + ip4_fib_mtrie_t *mtrie0, *mtrie1; + ip4_fib_mtrie_leaf_t leaf0, leaf1; + ip_source_and_port_range_check_config_t *c0, *c1; + ip_adjacency_t *adj0 = 0, *adj1 = 0; + u32 bi0, next0, adj_index0, pass0, save_next0, fib_index0; + u32 bi1, next1, adj_index1, pass1, save_next1, fib_index1; + udp_header_t *udp0, *udp1; + + /* Prefetch next iteration. */ + { + vlib_buffer_t *p2, *p3; + + p2 = vlib_get_buffer (vm, from[2]); + p3 = vlib_get_buffer (vm, from[3]); + + vlib_prefetch_buffer_header (p2, LOAD); + vlib_prefetch_buffer_header (p3, LOAD); + + CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD); + CLIB_PREFETCH (p3->data, sizeof (ip1[0]), LOAD); + } - CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD); - CLIB_PREFETCH (p3->data, sizeof (ip1[0]), LOAD); - } - - bi0 = to_next[0] = from[0]; - bi1 = to_next[1] = from[1]; - from += 2; - to_next += 2; - n_left_from -= 2; - n_left_to_next -= 2; - - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); - - fib_index0 = vec_elt (im->fib_index_by_sw_if_index, vnet_buffer (b0)->sw_if_index[VLIB_RX]); - fib_index1 = vec_elt (im->fib_index_by_sw_if_index, vnet_buffer (b1)->sw_if_index[VLIB_RX]); - - ip0 = vlib_buffer_get_current (b0); - ip1 = vlib_buffer_get_current (b1); - - c0 = vnet_get_config_data (&cm->config_main, - &b0->current_config_index, - &next0, - sizeof (c0[0])); - c1 = vnet_get_config_data (&cm->config_main, - &b1->current_config_index, - &next1, - sizeof (c1[0])); - - /* we can't use the default VRF here... */ - for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++) - { - ASSERT(c0->fib_index[i] && c1->fib_index[i]); - } - - - if (ip0->protocol == IP_PROTOCOL_UDP) - fib_index0 = c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT]; - if (ip0->protocol == IP_PROTOCOL_TCP) - fib_index0 = c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT]; - - if (PREDICT_TRUE(fib_index0 != ~0)) - { - - mtrie0 = &vec_elt_at_index (im->fibs, fib_index0)->mtrie; - - leaf0 = IP4_FIB_MTRIE_LEAF_ROOT; - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 0); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 1); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 2); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 3); - - adj_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); - - ASSERT (adj_index0 == ip4_fib_lookup_with_table (im, fib_index0, - &ip0->src_address, - 0 /* use dflt rt */)); - adj0 = ip_get_adjacency (lm, adj_index0); - } - - if (ip1->protocol == IP_PROTOCOL_UDP) - fib_index1 = c1->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT]; - if (ip1->protocol == IP_PROTOCOL_TCP) - fib_index1 = c1->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT]; - - if (PREDICT_TRUE(fib_index1 != ~0)) - { - - mtrie1 = &vec_elt_at_index (im->fibs, fib_index1)->mtrie; - - leaf1 = IP4_FIB_MTRIE_LEAF_ROOT; - - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, - &ip1->src_address, 0); - - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, - &ip1->src_address, 1); - - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, - &ip1->src_address, 2); - - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, - &ip1->src_address, 3); - - adj_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1); - - ASSERT (adj_index1 == ip4_fib_lookup_with_table (im, fib_index1, - &ip1->src_address, - 0)); - adj1 = ip_get_adjacency (lm, adj_index1); - } - - pass0 = 0; - pass0 |= adj0 == 0; - pass0 |= ip4_address_is_multicast (&ip0->src_address); - pass0 |= ip0->src_address.as_u32 == clib_host_to_net_u32(0xFFFFFFFF); - pass0 |= (ip0->protocol != IP_PROTOCOL_UDP) && - (ip0->protocol != IP_PROTOCOL_TCP); - - pass1 = 0; - pass1 |= adj1 == 0; - pass1 |= ip4_address_is_multicast (&ip1->src_address); - pass1 |= ip1->src_address.as_u32 == clib_host_to_net_u32(0xFFFFFFFF); - pass1 |= (ip1->protocol != IP_PROTOCOL_UDP) && - (ip1->protocol != IP_PROTOCOL_TCP); - - save_next0 = next0; - udp0 = ip4_next_header (ip0); - save_next1 = next1; - udp1 = ip4_next_header (ip1); - - if (PREDICT_TRUE(pass0 == 0)) - { - good_packets ++; - next0 = check_adj_port_range_x1 - (adj0, clib_net_to_host_u16(udp0->dst_port), next0); - good_packets -= (save_next0 != next0); - b0->error = error_node->errors - [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL]; - } - - if (PREDICT_TRUE(pass1 == 0)) - { - good_packets ++; - next1 = check_adj_port_range_x1 - (adj1, clib_net_to_host_u16(udp1->dst_port), next1); - good_packets -= (save_next1 != next1); - b1->error = error_node->errors - [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL]; - } - - if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) { - ip4_source_and_port_range_check_trace_t * t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->pass = next0 == save_next0; - t->bypass = pass0; - t->fib_index = fib_index0; - t->src_addr.as_u32 = ip0->src_address.as_u32; - t->dst_port = (pass0 == 0) ? - clib_net_to_host_u16(udp0->dst_port) : 0; - t->is_tcp = ip0->protocol == IP_PROTOCOL_TCP; - } - - if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) - && (b1->flags & VLIB_BUFFER_IS_TRACED))) { - ip4_source_and_port_range_check_trace_t * t = - vlib_add_trace (vm, node, b1, sizeof (*t)); - t->pass = next1 == save_next1; - t->bypass = pass1; - t->fib_index = fib_index1; - t->src_addr.as_u32 = ip1->src_address.as_u32; - t->dst_port = (pass1 == 0) ? - clib_net_to_host_u16(udp1->dst_port) : 0; - t->is_tcp = ip1->protocol == IP_PROTOCOL_TCP; - } - - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, - to_next, n_left_to_next, - bi0, bi1, next0, next1); - } + bi0 = to_next[0] = from[0]; + bi1 = to_next[1] = from[1]; + from += 2; + to_next += 2; + n_left_from -= 2; + n_left_to_next -= 2; + + b0 = vlib_get_buffer (vm, bi0); + b1 = vlib_get_buffer (vm, bi1); + + fib_index0 = + vec_elt (im->fib_index_by_sw_if_index, + vnet_buffer (b0)->sw_if_index[VLIB_RX]); + fib_index1 = + vec_elt (im->fib_index_by_sw_if_index, + vnet_buffer (b1)->sw_if_index[VLIB_RX]); + + ip0 = vlib_buffer_get_current (b0); + ip1 = vlib_buffer_get_current (b1); + + c0 = vnet_get_config_data (&cm->config_main, + &b0->current_config_index, + &next0, sizeof (c0[0])); + c1 = vnet_get_config_data (&cm->config_main, + &b1->current_config_index, + &next1, sizeof (c1[0])); + + /* we can't use the default VRF here... */ + for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++) + { + ASSERT (c0->fib_index[i] && c1->fib_index[i]); + } + + + if (ip0->protocol == IP_PROTOCOL_UDP) + fib_index0 = + c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT]; + if (ip0->protocol == IP_PROTOCOL_TCP) + fib_index0 = + c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT]; + + if (PREDICT_TRUE (fib_index0 != ~0)) + { + + mtrie0 = &vec_elt_at_index (im->fibs, fib_index0)->mtrie; + + leaf0 = IP4_FIB_MTRIE_LEAF_ROOT; + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 0); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 1); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 2); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 3); + + adj_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); + + ASSERT (adj_index0 == ip4_fib_lookup_with_table (im, fib_index0, + &ip0-> + src_address, + 0 + /* use dflt rt */ + )); + adj0 = ip_get_adjacency (lm, adj_index0); + } + + if (ip1->protocol == IP_PROTOCOL_UDP) + fib_index1 = + c1->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT]; + if (ip1->protocol == IP_PROTOCOL_TCP) + fib_index1 = + c1->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT]; + + if (PREDICT_TRUE (fib_index1 != ~0)) + { + + mtrie1 = &vec_elt_at_index (im->fibs, fib_index1)->mtrie; + + leaf1 = IP4_FIB_MTRIE_LEAF_ROOT; + + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, + &ip1->src_address, 0); + + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, + &ip1->src_address, 1); + + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, + &ip1->src_address, 2); + + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, + &ip1->src_address, 3); + + adj_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1); + + ASSERT (adj_index1 == ip4_fib_lookup_with_table (im, fib_index1, + &ip1-> + src_address, + 0)); + adj1 = ip_get_adjacency (lm, adj_index1); + } + + pass0 = 0; + pass0 |= adj0 == 0; + pass0 |= ip4_address_is_multicast (&ip0->src_address); + pass0 |= + ip0->src_address.as_u32 == clib_host_to_net_u32 (0xFFFFFFFF); + pass0 |= (ip0->protocol != IP_PROTOCOL_UDP) + && (ip0->protocol != IP_PROTOCOL_TCP); + + pass1 = 0; + pass1 |= adj1 == 0; + pass1 |= ip4_address_is_multicast (&ip1->src_address); + pass1 |= + ip1->src_address.as_u32 == clib_host_to_net_u32 (0xFFFFFFFF); + pass1 |= (ip1->protocol != IP_PROTOCOL_UDP) + && (ip1->protocol != IP_PROTOCOL_TCP); + + save_next0 = next0; + udp0 = ip4_next_header (ip0); + save_next1 = next1; + udp1 = ip4_next_header (ip1); + + if (PREDICT_TRUE (pass0 == 0)) + { + good_packets++; + next0 = check_adj_port_range_x1 + (adj0, clib_net_to_host_u16 (udp0->dst_port), next0); + good_packets -= (save_next0 != next0); + b0->error = error_node->errors + [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL]; + } + + if (PREDICT_TRUE (pass1 == 0)) + { + good_packets++; + next1 = check_adj_port_range_x1 + (adj1, clib_net_to_host_u16 (udp1->dst_port), next1); + good_packets -= (save_next1 != next1); + b1->error = error_node->errors + [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL]; + } + + if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) + && (b0->flags & VLIB_BUFFER_IS_TRACED))) + { + ip4_source_and_port_range_check_trace_t *t = + vlib_add_trace (vm, node, b0, sizeof (*t)); + t->pass = next0 == save_next0; + t->bypass = pass0; + t->fib_index = fib_index0; + t->src_addr.as_u32 = ip0->src_address.as_u32; + t->dst_port = (pass0 == 0) ? + clib_net_to_host_u16 (udp0->dst_port) : 0; + t->is_tcp = ip0->protocol == IP_PROTOCOL_TCP; + } + + if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) + && (b1->flags & VLIB_BUFFER_IS_TRACED))) + { + ip4_source_and_port_range_check_trace_t *t = + vlib_add_trace (vm, node, b1, sizeof (*t)); + t->pass = next1 == save_next1; + t->bypass = pass1; + t->fib_index = fib_index1; + t->src_addr.as_u32 = ip1->src_address.as_u32; + t->dst_port = (pass1 == 0) ? + clib_net_to_host_u16 (udp1->dst_port) : 0; + t->is_tcp = ip1->protocol == IP_PROTOCOL_TCP; + } + + vlib_validate_buffer_enqueue_x2 (vm, node, next_index, + to_next, n_left_to_next, + bi0, bi1, next0, next1); + } while (n_left_from > 0 && n_left_to_next > 0) - { - vlib_buffer_t * b0; - ip4_header_t * ip0; - ip4_fib_mtrie_t * mtrie0; - ip4_fib_mtrie_leaf_t leaf0; - ip_source_and_port_range_check_config_t * c0; - ip_adjacency_t * adj0 = 0; - u32 bi0, next0, adj_index0, pass0, save_next0, fib_index0; - udp_header_t * udp0; - - bi0 = from[0]; - to_next[0] = bi0; - from += 1; - to_next += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - - fib_index0 = vec_elt (im->fib_index_by_sw_if_index, vnet_buffer (b0)->sw_if_index[VLIB_RX]); - - ip0 = vlib_buffer_get_current (b0); - - c0 = vnet_get_config_data - (&cm->config_main, &b0->current_config_index, - &next0, - sizeof (c0[0])); - - /* we can't use the default VRF here... */ - for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++) - { - ASSERT(c0->fib_index[i]); - } - - - if (ip0->protocol == IP_PROTOCOL_UDP) - fib_index0 = c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT]; - if (ip0->protocol == IP_PROTOCOL_TCP) - fib_index0 = c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT]; - - if (fib_index0 != ~0) - { - - mtrie0 = &vec_elt_at_index (im->fibs, fib_index0)->mtrie; - - leaf0 = IP4_FIB_MTRIE_LEAF_ROOT; - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 0); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 1); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 2); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, - &ip0->src_address, 3); - - adj_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); - - ASSERT (adj_index0 == ip4_fib_lookup_with_table - (im, fib_index0, - &ip0->src_address, - 0 /* use default route */)); - adj0 = ip_get_adjacency (lm, adj_index0); - } - /* - * $$$ which (src,dst) categories should we always pass? - */ - pass0 = 0; - pass0 |= adj0 == 0; - pass0 |= ip4_address_is_multicast (&ip0->src_address); - pass0 |= ip0->src_address.as_u32 == clib_host_to_net_u32(0xFFFFFFFF); - pass0 |= (ip0->protocol != IP_PROTOCOL_UDP) && - (ip0->protocol != IP_PROTOCOL_TCP); - - save_next0 = next0; - udp0 = ip4_next_header (ip0); - - if (PREDICT_TRUE(pass0 == 0)) - { - good_packets ++; - next0 = check_adj_port_range_x1 - (adj0, clib_net_to_host_u16(udp0->dst_port), next0); - good_packets -= (save_next0 != next0); - b0->error = error_node->errors - [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL]; - } - - if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) { - ip4_source_and_port_range_check_trace_t * t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->pass = next0 == save_next0; - t->bypass = pass0; - t->fib_index = fib_index0; - t->src_addr.as_u32 = ip0->src_address.as_u32; - t->dst_port = (pass0 == 0) ? - clib_net_to_host_u16(udp0->dst_port) : 0; - t->is_tcp = ip0->protocol == IP_PROTOCOL_TCP; - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, - bi0, next0); - } + { + vlib_buffer_t *b0; + ip4_header_t *ip0; + ip4_fib_mtrie_t *mtrie0; + ip4_fib_mtrie_leaf_t leaf0; + ip_source_and_port_range_check_config_t *c0; + ip_adjacency_t *adj0 = 0; + u32 bi0, next0, adj_index0, pass0, save_next0, fib_index0; + udp_header_t *udp0; + + bi0 = from[0]; + to_next[0] = bi0; + from += 1; + to_next += 1; + n_left_from -= 1; + n_left_to_next -= 1; + + b0 = vlib_get_buffer (vm, bi0); + + fib_index0 = + vec_elt (im->fib_index_by_sw_if_index, + vnet_buffer (b0)->sw_if_index[VLIB_RX]); + + ip0 = vlib_buffer_get_current (b0); + + c0 = vnet_get_config_data + (&cm->config_main, &b0->current_config_index, + &next0, sizeof (c0[0])); + + /* we can't use the default VRF here... */ + for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++) + { + ASSERT (c0->fib_index[i]); + } + + + if (ip0->protocol == IP_PROTOCOL_UDP) + fib_index0 = + c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT]; + if (ip0->protocol == IP_PROTOCOL_TCP) + fib_index0 = + c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT]; + + if (fib_index0 != ~0) + { + + mtrie0 = &vec_elt_at_index (im->fibs, fib_index0)->mtrie; + + leaf0 = IP4_FIB_MTRIE_LEAF_ROOT; + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 0); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 1); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 2); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, + &ip0->src_address, 3); + + adj_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); + + ASSERT (adj_index0 == ip4_fib_lookup_with_table + (im, fib_index0, + &ip0->src_address, 0 /* use default route */ )); + adj0 = ip_get_adjacency (lm, adj_index0); + } + /* + * $$$ which (src,dst) categories should we always pass? + */ + pass0 = 0; + pass0 |= adj0 == 0; + pass0 |= ip4_address_is_multicast (&ip0->src_address); + pass0 |= + ip0->src_address.as_u32 == clib_host_to_net_u32 (0xFFFFFFFF); + pass0 |= (ip0->protocol != IP_PROTOCOL_UDP) + && (ip0->protocol != IP_PROTOCOL_TCP); + + save_next0 = next0; + udp0 = ip4_next_header (ip0); + + if (PREDICT_TRUE (pass0 == 0)) + { + good_packets++; + next0 = check_adj_port_range_x1 + (adj0, clib_net_to_host_u16 (udp0->dst_port), next0); + good_packets -= (save_next0 != next0); + b0->error = error_node->errors + [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL]; + } + + if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) + && (b0->flags & VLIB_BUFFER_IS_TRACED))) + { + ip4_source_and_port_range_check_trace_t *t = + vlib_add_trace (vm, node, b0, sizeof (*t)); + t->pass = next0 == save_next0; + t->bypass = pass0; + t->fib_index = fib_index0; + t->src_addr.as_u32 = ip0->src_address.as_u32; + t->dst_port = (pass0 == 0) ? + clib_net_to_host_u16 (udp0->dst_port) : 0; + t->is_tcp = ip0->protocol == IP_PROTOCOL_TCP; + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, + to_next, n_left_to_next, + bi0, next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, ip4_source_port_and_range_check.index, - IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK, - good_packets); + IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK, + good_packets); return frame->n_vectors; } static uword ip4_source_and_port_range_check (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return ip4_source_and_port_range_check_inline (vm, node, frame); } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip4_source_port_and_range_check) = { .function = ip4_source_and_port_range_check, .name = "ip4-source-and-port-range-check", @@ -479,15 +503,16 @@ VLIB_REGISTER_NODE (ip4_source_port_and_range_check) = { .format_buffer = format_ip4_header, .format_trace = format_ip4_source_and_port_range_check_trace, }; +/* *INDENT-ON* */ -int set_ip_source_and_port_range_check (vlib_main_t * vm, - u32 * fib_index, - u32 sw_if_index, - u32 is_add) +int +set_ip_source_and_port_range_check (vlib_main_t * vm, + u32 * fib_index, + u32 sw_if_index, u32 is_add) { - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - ip_config_main_t * rx_cm = &lm->rx_config_mains[VNET_UNICAST]; + ip4_main_t *im = &ip4_main; + ip_lookup_main_t *lm = &im->lookup_main; + ip_config_main_t *rx_cm = &lm->rx_config_mains[VNET_UNICAST]; u32 ci; ip_source_and_port_range_check_config_t config; u32 feature_index; @@ -505,13 +530,9 @@ int set_ip_source_and_port_range_check (vlib_main_t * vm, ci = rx_cm->config_index_by_sw_if_index[sw_if_index]; ci = (is_add - ? vnet_config_add_feature - : vnet_config_del_feature) - (vm, &rx_cm->config_main, - ci, - feature_index, - &config, - sizeof (config)); + ? vnet_config_add_feature + : vnet_config_del_feature) + (vm, &rx_cm->config_main, ci, feature_index, &config, sizeof (config)); rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; return rv; @@ -519,18 +540,18 @@ int set_ip_source_and_port_range_check (vlib_main_t * vm, static clib_error_t * set_ip_source_and_port_range_check_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - vnet_main_t * vnm = vnet_get_main(); - ip4_main_t * im = &ip4_main; - clib_error_t * error = 0; + vnet_main_t *vnm = vnet_get_main (); + ip4_main_t *im = &ip4_main; + clib_error_t *error = 0; u8 is_add = 1; u32 sw_if_index = ~0; u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS]; u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS]; int vrf_set = 0; - uword * p; + uword *p; int rv = 0; int i; @@ -544,74 +565,94 @@ set_ip_source_and_port_range_check_fn (vlib_main_t * vm, while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, - &sw_if_index)) - ; - else if (unformat (input, "tcp-out-vrf %d", &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT])) - vrf_set = 1; - else if (unformat (input, "udp-out-vrf %d", &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT])) - vrf_set = 1; - else if (unformat (input, "tcp-in-vrf %d", &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN])) - vrf_set = 1; - else if (unformat (input, "udp-in-vrf %d", &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN])) - vrf_set = 1; + &sw_if_index)) + ; + else + if (unformat + (input, "tcp-out-vrf %d", + &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT])) + vrf_set = 1; + else + if (unformat + (input, "udp-out-vrf %d", + &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT])) + vrf_set = 1; + else + if (unformat + (input, "tcp-in-vrf %d", + &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN])) + vrf_set = 1; + else + if (unformat + (input, "udp-in-vrf %d", + &vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN])) + vrf_set = 1; else if (unformat (input, "del")) - is_add = 0; + is_add = 0; else - break; + break; } if (sw_if_index == ~0) return clib_error_return (0, "Interface required but not specified"); if (!vrf_set) - return clib_error_return (0, "TCP or UDP VRF ID required but not specified"); + return clib_error_return (0, + "TCP or UDP VRF ID required but not specified"); for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++) { if (vrf_id[i] == 0) - return clib_error_return (0, "TCP, UDP VRF ID should not be 0 (default). Should be distinct VRF for this purpose. "); + return clib_error_return (0, + "TCP, UDP VRF ID should not be 0 (default). Should be distinct VRF for this purpose. "); if (vrf_id[i] != ~0) - { - p = hash_get (im->fib_index_by_table_id, vrf_id[i]); + { + p = hash_get (im->fib_index_by_table_id, vrf_id[i]); - if (p == 0) - return clib_error_return (0, "Invalid VRF ID %d", vrf_id[i]); + if (p == 0) + return clib_error_return (0, "Invalid VRF ID %d", vrf_id[i]); - fib_index[i] = p[0]; - } + fib_index[i] = p[0]; + } } - rv = set_ip_source_and_port_range_check (vm, fib_index, sw_if_index, is_add); + rv = + set_ip_source_and_port_range_check (vm, fib_index, sw_if_index, is_add); - switch(rv) + switch (rv) { case 0: break; default: return clib_error_return - (0, "set source and port-range on interface returned an unexpected value: %d", rv); + (0, + "set source and port-range on interface returned an unexpected value: %d", + rv); } return error; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_interface_ip_source_and_port_range_check_command, static) = { .path = "set interface ip source-and-port-range-check", .function = set_ip_source_and_port_range_check_fn, .short_help = "set int ip source-and-port-range-check <intfc> [tcp-out-vrf <n>] [udp-out-vrf <n>] [tcp-in-vrf <n>] [udp-in-vrf <n>] [del]", }; +/* *INDENT-ON* */ -static u8 * format_source_and_port_rc_adjacency (u8 * s, va_list * args) +static u8 * +format_source_and_port_rc_adjacency (u8 * s, va_list * args) { CLIB_UNUSED (vnet_main_t * vnm) = va_arg (*args, vnet_main_t *); - ip_lookup_main_t * lm = va_arg (*args, ip_lookup_main_t *); + ip_lookup_main_t *lm = va_arg (*args, ip_lookup_main_t *); u32 adj_index = va_arg (*args, u32); - ip_adjacency_t * adj = ip_get_adjacency (lm, adj_index); - source_range_check_main_t * srm = &source_range_check_main; - u8 * rwh = (u8 *) (&adj->rewrite_header); - protocol_port_range_t * range; + ip_adjacency_t *adj = ip_get_adjacency (lm, adj_index); + source_range_check_main_t *srm = &source_range_check_main; + u8 *rwh = (u8 *) (&adj->rewrite_header); + protocol_port_range_t *range; int i, j; int printed = 0; @@ -622,37 +663,39 @@ static u8 * format_source_and_port_rc_adjacency (u8 * s, va_list * args) for (i = 0; i < srm->ranges_per_adjacency; i++) { for (j = 0; j < 8; j++) - { - if (range->low.as_u16[j]) - { - if (printed) - s = format (s, ", "); - if (range->hi.as_u16[j] > (range->low.as_u16[j] + 1)) - s = format (s, "%d-%d", (u32) range->low.as_u16[j], - (u32) range->hi.as_u16[j] - 1); - else - s = format (s, "%d", range->low.as_u16[j]); - printed = 1; - } - } + { + if (range->low.as_u16[j]) + { + if (printed) + s = format (s, ", "); + if (range->hi.as_u16[j] > (range->low.as_u16[j] + 1)) + s = format (s, "%d-%d", (u32) range->low.as_u16[j], + (u32) range->hi.as_u16[j] - 1); + else + s = format (s, "%d", range->low.as_u16[j]); + printed = 1; + } + } range++; } return s; } -clib_error_t * ip4_source_and_port_range_check_init (vlib_main_t * vm) +clib_error_t * +ip4_source_and_port_range_check_init (vlib_main_t * vm) { - source_range_check_main_t * srm = &source_range_check_main; - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; + source_range_check_main_t *srm = &source_range_check_main; + ip4_main_t *im = &ip4_main; + ip_lookup_main_t *lm = &im->lookup_main; srm->vlib_main = vm; - srm->vnet_main = vnet_get_main(); + srm->vnet_main = vnet_get_main (); - srm->ranges_per_adjacency = VLIB_BUFFER_PRE_DATA_SIZE / (2*sizeof(u16x8)); + srm->ranges_per_adjacency = + VLIB_BUFFER_PRE_DATA_SIZE / (2 * sizeof (u16x8)); srm->special_adjacency_format_function_index = - vnet_register_special_adjacency_format_function - (lm, format_source_and_port_rc_adjacency); + vnet_register_special_adjacency_format_function (lm, + format_source_and_port_rc_adjacency); ASSERT (srm->special_adjacency_format_function_index); return 0; @@ -660,19 +703,18 @@ clib_error_t * ip4_source_and_port_range_check_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ip4_source_and_port_range_check_init); -int add_port_range_adjacency(ip4_address_t * address, - u32 length, - u32 adj_index, - u16 * low_ports, - u16 * high_ports, - u32 fib_index) +int +add_port_range_adjacency (ip4_address_t * address, + u32 length, + u32 adj_index, + u16 * low_ports, u16 * high_ports, u32 fib_index) { - ip_adjacency_t * adj; + ip_adjacency_t *adj; int i, j, k; - source_range_check_main_t * srm = &source_range_check_main; - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - protocol_port_range_t * range; + source_range_check_main_t *srm = &source_range_check_main; + ip4_main_t *im = &ip4_main; + ip_lookup_main_t *lm = &im->lookup_main; + protocol_port_range_t *range; u8 *rwh; adj = ip_get_adjacency (lm, adj_index); @@ -702,33 +744,33 @@ int add_port_range_adjacency(ip4_address_t * address, for (i = 0; i < vec_len (low_ports); i++) { for (; j < srm->ranges_per_adjacency; j++) - { - for (; k < 8; k++) - { - if (range->low.as_u16[k] == 0) - { - range->low.as_u16[k] = low_ports[i]; - range->hi.as_u16[k] = high_ports[i]; - k++; - if (k == 7) - { - k = 0; - j++; - } - goto doublebreak2; - } - } - k = 0; - range++; - } + { + for (; k < 8; k++) + { + if (range->low.as_u16[k] == 0) + { + range->low.as_u16[k] = low_ports[i]; + range->hi.as_u16[k] = high_ports[i]; + k++; + if (k == 7) + { + k = 0; + j++; + } + goto doublebreak2; + } + } + k = 0; + range++; + } j = 0; /* Too many ports specified... */ return VNET_API_ERROR_EXCEEDED_NUMBER_OF_PORTS_CAPACITY; - doublebreak2: ; + doublebreak2:; } - memset (&a, 0, sizeof(a)); + memset (&a, 0, sizeof (a)); a.flags = IP4_ROUTE_FLAG_FIB_INDEX; a.table_index_or_table_id = fib_index; a.dst_address = address[0]; @@ -740,44 +782,43 @@ int add_port_range_adjacency(ip4_address_t * address, return 0; } -int remove_port_range_adjacency(ip4_address_t * address, - u32 length, - u32 adj_index, - u16 * low_ports, - u16 * high_ports, - u32 fib_index) +int +remove_port_range_adjacency (ip4_address_t * address, + u32 length, + u32 adj_index, + u16 * low_ports, u16 * high_ports, u32 fib_index) { - ip_adjacency_t * adj; + ip_adjacency_t *adj; int i, j, k; - source_range_check_main_t * srm = &source_range_check_main; - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - protocol_port_range_t * range; + source_range_check_main_t *srm = &source_range_check_main; + ip4_main_t *im = &ip4_main; + ip_lookup_main_t *lm = &im->lookup_main; + protocol_port_range_t *range; u8 *rwh; adj = ip_get_adjacency (lm, adj_index); - if (adj->lookup_next_index != IP_LOOKUP_NEXT_ICMP_ERROR) /* _ICMP_ERROR is a dummy placeholder */ + if (adj->lookup_next_index != IP_LOOKUP_NEXT_ICMP_ERROR) /* _ICMP_ERROR is a dummy placeholder */ return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE; - rwh = (u8 *)(&adj->rewrite_header); + rwh = (u8 *) (&adj->rewrite_header); for (i = 0; i < vec_len (low_ports); i++) { range = (protocol_port_range_t *) rwh; for (j = 0; j < srm->ranges_per_adjacency; j++) - { - for (k = 0; k < 8; k++) - { - if (low_ports[i] == range->low.as_u16[k] && - high_ports[i] == range->hi.as_u16[k]) - { - range->low.as_u16[k] = range->hi.as_u16[k] = 0; - goto doublebreak; - } - } - range++; - } - doublebreak: ; + { + for (k = 0; k < 8; k++) + { + if (low_ports[i] == range->low.as_u16[k] && + high_ports[i] == range->hi.as_u16[k]) + { + range->low.as_u16[k] = range->hi.as_u16[k] = 0; + goto doublebreak; + } + } + range++; + } + doublebreak:; } range = (protocol_port_range_t *) rwh; @@ -785,17 +826,17 @@ int remove_port_range_adjacency(ip4_address_t * address, for (i = 0; i < srm->ranges_per_adjacency; i++) { for (j = 0; j < 8; j++) - { - if (range->low.as_u16[i] != 0) - goto still_occupied; - } + { + if (range->low.as_u16[i] != 0) + goto still_occupied; + } range++; } /* Yes, lose the adjacency... */ { ip4_add_del_route_args_t a; - memset (&a, 0, sizeof(a)); + memset (&a, 0, sizeof (a)); a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL; a.table_index_or_table_id = fib_index; a.dst_address = address[0]; @@ -804,55 +845,58 @@ int remove_port_range_adjacency(ip4_address_t * address, ip4_add_del_route (im, &a); } - still_occupied: +still_occupied: ; return 0; } // This will be moved to another file and implemented post API freeze. -int ip6_source_and_port_range_check_add_del (ip6_address_t * address, - u32 length, - u32 vrf_id, - u16 * low_ports, - u16 * high_ports, - int is_add) +int +ip6_source_and_port_range_check_add_del (ip6_address_t * address, + u32 length, + u32 vrf_id, + u16 * low_ports, + u16 * high_ports, int is_add) { return 0; } -int ip4_source_and_port_range_check_add_del (ip4_address_t * address, - u32 length, - u32 vrf_id, - u16 * low_ports, - u16 * high_ports, - int is_add) + +int +ip4_source_and_port_range_check_add_del (ip4_address_t * address, + u32 length, + u32 vrf_id, + u16 * low_ports, + u16 * high_ports, int is_add) { - ip4_main_t * im = &ip4_main; + ip4_main_t *im = &ip4_main; // ip_lookup_main_t * lm = &im->lookup_main; - uword * p; + uword *p; u32 fib_index; u32 adj_index; p = hash_get (im->fib_index_by_table_id, vrf_id); if (!p) { - ip4_fib_t * f; - f = find_ip4_fib_by_table_index_or_id (im, vrf_id, 0 /* flags */); + ip4_fib_t *f; + f = find_ip4_fib_by_table_index_or_id (im, vrf_id, 0 /* flags */ ); fib_index = f->index; } else fib_index = p[0]; adj_index = ip4_fib_lookup_with_table - (im, fib_index, address, 0 /* disable_default_route */); + (im, fib_index, address, 0 /* disable_default_route */ ); if (is_add == 0) { - remove_port_range_adjacency(address, length, adj_index, low_ports, high_ports, fib_index); + remove_port_range_adjacency (address, length, adj_index, low_ports, + high_ports, fib_index); } else { - add_port_range_adjacency(address, length, adj_index, low_ports, high_ports, fib_index); + add_port_range_adjacency (address, length, adj_index, low_ports, + high_ports, fib_index); } return 0; @@ -860,15 +904,15 @@ int ip4_source_and_port_range_check_add_del (ip4_address_t * address, static clib_error_t * ip_source_and_port_range_check_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - u16 * low_ports = 0; - u16 * high_ports = 0; + u16 *low_ports = 0; + u16 *high_ports = 0; u16 this_low; u16 this_hi; ip4_address_t ip4_addr; - ip6_address_t ip6_addr; //This function will be moved to generic impl when v6 done. + ip6_address_t ip6_addr; //This function will be moved to generic impl when v6 done. u32 length; u32 tmp, tmp2; u32 vrf_id = ~0; @@ -879,38 +923,40 @@ ip_source_and_port_range_check_command_fn (vlib_main_t * vm, while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length)) - ip_ver = 4; - else if (unformat (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length)) - ip_ver = 6; + ip_ver = 4; + else + if (unformat + (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length)) + ip_ver = 6; else if (unformat (input, "vrf %d", &vrf_id)) - ; + ; else if (unformat (input, "del")) - is_add = 0; + is_add = 0; else if (unformat (input, "port %d", &tmp)) - { - if (tmp == 0 || tmp > 65535) - return clib_error_return (0, "port %d out of range", tmp); - this_low = tmp; - this_hi = this_low + 1; - vec_add1 (low_ports, this_low); - vec_add1 (high_ports, this_hi); - } + { + if (tmp == 0 || tmp > 65535) + return clib_error_return (0, "port %d out of range", tmp); + this_low = tmp; + this_hi = this_low + 1; + vec_add1 (low_ports, this_low); + vec_add1 (high_ports, this_hi); + } else if (unformat (input, "range %d - %d", &tmp, &tmp2)) - { - if (tmp > tmp2) - return clib_error_return (0, "ports %d and %d out of order", - tmp, tmp2); - if (tmp == 0 || tmp > 65535) - return clib_error_return (0, "low port %d out of range", tmp); - if (tmp2 == 0 || tmp2 > 65535) - return clib_error_return (0, "high port %d out of range", tmp2); - this_low = tmp; - this_hi = tmp2+1; - vec_add1 (low_ports, this_low); - vec_add1 (high_ports, this_hi); - } + { + if (tmp > tmp2) + return clib_error_return (0, "ports %d and %d out of order", + tmp, tmp2); + if (tmp == 0 || tmp > 65535) + return clib_error_return (0, "low port %d out of range", tmp); + if (tmp2 == 0 || tmp2 > 65535) + return clib_error_return (0, "high port %d out of range", tmp2); + this_low = tmp; + this_hi = tmp2 + 1; + vec_add1 (low_ports, this_low); + vec_add1 (high_ports, this_hi); + } else - break; + break; } if (ip_ver == ~0) @@ -919,8 +965,9 @@ ip_source_and_port_range_check_command_fn (vlib_main_t * vm, if (vrf_id == ~0) return clib_error_return (0, " VRF ID required, not specified"); - if ( vec_len (low_ports) == 0) - return clib_error_return (0, " Both VRF ID and range/port must be set for a protocol."); + if (vec_len (low_ports) == 0) + return clib_error_return (0, + " Both VRF ID and range/port must be set for a protocol."); if (vrf_id == 0) return clib_error_return (0, " VRF ID can not be 0 (default)."); @@ -930,50 +977,50 @@ ip_source_and_port_range_check_command_fn (vlib_main_t * vm, rv = ip4_source_and_port_range_check_add_del (&ip4_addr, length, vrf_id, low_ports, high_ports, is_add); else - return clib_error_return (0, " IPv6 in subsequent patch"); + return clib_error_return (0, " IPv6 in subsequent patch"); - switch(rv) + switch (rv) { case 0: break; case VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE: return clib_error_return - (0, " Incorrect adjacency for add/del operation"); + (0, " Incorrect adjacency for add/del operation"); case VNET_API_ERROR_EXCEEDED_NUMBER_OF_PORTS_CAPACITY: - return clib_error_return - (0, " Too many ports in add/del operation"); + return clib_error_return (0, " Too many ports in add/del operation"); case VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY: return clib_error_return - (0, " Too many ranges requested for add operation"); + (0, " Too many ranges requested for add operation"); default: - return clib_error_return - (0, " returned an unexpected value: %d", rv); + return clib_error_return (0, " returned an unexpected value: %d", rv); } return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ip_source_and_port_range_check_command, static) = { .path = "set ip source-and-port-range-check", .function = ip_source_and_port_range_check_command_fn, .short_help = "set ip source-and-port-range-check <ip-addr>/<mask> [range <nn>-<nn> tcp-vrf <id>] [vrf <id>] [del]", }; +/* *INDENT-ON* */ static clib_error_t * show_source_and_port_range_check_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - source_range_check_main_t * srm = & source_range_check_main; - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - protocol_port_range_t * range; + source_range_check_main_t *srm = &source_range_check_main; + ip4_main_t *im = &ip4_main; + ip_lookup_main_t *lm = &im->lookup_main; + protocol_port_range_t *range; u32 fib_index; ip4_address_t addr; u8 addr_set = 0; @@ -982,19 +1029,19 @@ show_source_and_port_range_check_fn (vlib_main_t * vm, u32 adj_index; ip_adjacency_t *adj; u32 port = 0; - u8 * rwh; - uword * p; + u8 *rwh; + uword *p; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%U", unformat_ip4_address, &addr)) - addr_set = 1; + addr_set = 1; else if (unformat (input, "vrf %d", &vrf_id)) - ; + ; else if (unformat (input, "port %d", &port)) - ; + ; else - break; + break; } if (addr_set == 0) @@ -1009,7 +1056,7 @@ show_source_and_port_range_check_fn (vlib_main_t * vm, fib_index = p[0]; adj_index = ip4_fib_lookup_with_table - (im, fib_index, &addr, 0 /* disable_default_route */); + (im, fib_index, &addr, 0 /* disable_default_route */ ); adj = ip_get_adjacency (lm, adj_index); @@ -1023,16 +1070,16 @@ show_source_and_port_range_check_fn (vlib_main_t * vm, { rv = check_adj_port_range_x1 (adj, (u16) port, 1234); if (rv == 1234) - vlib_cli_output (vm, "%U port %d PASS", format_ip4_address, - &addr, port); + vlib_cli_output (vm, "%U port %d PASS", format_ip4_address, + &addr, port); else - vlib_cli_output (vm, "%U port %d FAIL", format_ip4_address, - &addr, port); + vlib_cli_output (vm, "%U port %d FAIL", format_ip4_address, + &addr, port); return 0; } else { - u8 * s; + u8 *s; rwh = (u8 *) (&adj->rewrite_header); s = format (0, "%U: ", format_ip4_address, &addr); @@ -1040,25 +1087,35 @@ show_source_and_port_range_check_fn (vlib_main_t * vm, range = (protocol_port_range_t *) rwh; for (i = 0; i < srm->ranges_per_adjacency; i++) - { - for (j = 0; j < 8; j++) - { - if (range->low.as_u16[j]) - s = format (s, "%d - %d ", (u32) range->low.as_u16[j], - (u32) range->hi.as_u16[j]); - } - range++; - } + { + for (j = 0; j < 8; j++) + { + if (range->low.as_u16[j]) + s = format (s, "%d - %d ", (u32) range->low.as_u16[j], + (u32) range->hi.as_u16[j]); + } + range++; + } vlib_cli_output (vm, "%s", s); - vec_free(s); + vec_free (s); } return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_source_and_port_range_check, static) = { .path = "show ip source-and-port-range-check", .function = show_source_and_port_range_check_fn, .short_help = "show ip source-and-port-range-check vrf <nn> <ip-addr> <port>", }; +/* *INDENT-ON* */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ip/ip_source_and_port_range_check.h b/vnet/vnet/ip/ip_source_and_port_range_check.h index 1429057bf1d..5b49aabd849 100644 --- a/vnet/vnet/ip/ip_source_and_port_range_check.h +++ b/vnet/vnet/ip/ip_source_and_port_range_check.h @@ -17,7 +17,8 @@ #define included_ip_ip_source_and_port_range_check_h -typedef struct { +typedef struct +{ u32 ranges_per_adjacency; u32 special_adjacency_format_function_index; @@ -28,7 +29,8 @@ typedef struct { source_range_check_main_t source_range_check_main; -typedef enum { +typedef enum +{ IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT, IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT, IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN, @@ -36,42 +38,51 @@ typedef enum { IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS, } ip_source_and_port_range_check_protocol_t; -typedef struct { +typedef struct +{ u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS]; } ip_source_and_port_range_check_config_t; #define IP_SOURCE_AND_PORT_RANGE_CHECK_RANGE_LIMIT VLIB_BUFFER_PRE_DATA_SIZE/(2*sizeof(u16x8)); -typedef struct { - union { +typedef struct +{ + union + { u16x8 as_u16x8; u16 as_u16[8]; }; } u16x8vec_t; -typedef struct { +typedef struct +{ u16x8vec_t low; u16x8vec_t hi; } protocol_port_range_t; int ip4_source_and_port_range_check_add_del (ip4_address_t * address, - u32 length, - u32 vrf_id, - u16 * low_ports, - u16 * hi_ports, - int is_add); + u32 length, + u32 vrf_id, + u16 * low_ports, + u16 * hi_ports, int is_add); // This will be moved to another file in another patch -- for API freeze int ip6_source_and_port_range_check_add_del (ip6_address_t * address, - u32 length, - u32 vrf_id, - u16 * low_ports, - u16 * hi_ports, - int is_add); + u32 length, + u32 vrf_id, + u16 * low_ports, + u16 * hi_ports, int is_add); int set_ip_source_and_port_range_check (vlib_main_t * vm, - u32 * fib_index, - u32 sw_if_index, - u32 is_add); + u32 * fib_index, + u32 sw_if_index, u32 is_add); #endif /* included ip_source_and_port_range_check_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |