X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsrv6%2Fsr_policy_rewrite.c;h=62ce224cd8e6a22f31a9e46d6771e7b42c2dcea0;hb=84f36cb0963d9aa5b1d235baedffbdb20f839cfa;hp=2f90993a4be77bfc4ab89fc1e87a9fea21a7fee6;hpb=1500254bee11355bbd69cc1dd9705be4f002f2bd;p=vpp.git diff --git a/src/vnet/srv6/sr_policy_rewrite.c b/src/vnet/srv6/sr_policy_rewrite.c index 2f90993a4be..62ce224cd8e 100755 --- a/src/vnet/srv6/sr_policy_rewrite.c +++ b/src/vnet/srv6/sr_policy_rewrite.c @@ -112,6 +112,12 @@ static ip6_address_t sr_pr_encaps_src; /* Note: This is temporal. We don't know whether to follow this path or take the ip address of a loopback interface or even the OIF */ +void +sr_set_source (ip6_address_t * address) +{ + clib_memcpy (&sr_pr_encaps_src, address, sizeof (sr_pr_encaps_src)); +} + static clib_error_t * set_sr_src_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -171,22 +177,26 @@ compute_rewrite_encaps (ip6_address_t * sl) iph->protocol = IP_PROTOCOL_IPV6; iph->hop_limit = IPv6_DEFAULT_HOP_LIMIT; - srh = (ip6_sr_header_t *) (iph + 1); - iph->protocol = IP_PROTOCOL_IPV6_ROUTE; - srh->protocol = IP_PROTOCOL_IPV6; - srh->type = ROUTING_HEADER_TYPE_SR; - srh->segments_left = vec_len (sl) - 1; - srh->first_segment = vec_len (sl) - 1; - srh->length = ((sizeof (ip6_sr_header_t) + - (vec_len (sl) * sizeof (ip6_address_t))) / 8) - 1; - srh->flags = 0x00; - srh->reserved = 0x00; - addrp = srh->segments + vec_len (sl) - 1; - vec_foreach (this_address, sl) - { - clib_memcpy (addrp->as_u8, this_address->as_u8, sizeof (ip6_address_t)); - addrp--; - } + if (vec_len (sl) > 1) + { + srh = (ip6_sr_header_t *) (iph + 1); + iph->protocol = IP_PROTOCOL_IPV6_ROUTE; + srh->protocol = IP_PROTOCOL_IPV6; + srh->type = ROUTING_HEADER_TYPE_SR; + srh->segments_left = vec_len (sl) - 1; + srh->first_segment = vec_len (sl) - 1; + srh->length = ((sizeof (ip6_sr_header_t) + + (vec_len (sl) * sizeof (ip6_address_t))) / 8) - 1; + srh->flags = 0x00; + srh->reserved = 0x00; + addrp = srh->segments + vec_len (sl) - 1; + vec_foreach (this_address, sl) + { + clib_memcpy (addrp->as_u8, this_address->as_u8, + sizeof (ip6_address_t)); + addrp--; + } + } iph->dst_address.as_u64[0] = sl->as_u64[0]; iph->dst_address.as_u64[1] = sl->as_u64[1]; return rs; @@ -367,7 +377,7 @@ update_lb (ip6_sr_policy_t * sr_policy) /* Add FIB entry for BSID */ fhc = fib_table_get_flow_hash_config (sr_policy->fib_table, - dpo_proto_to_fib (DPO_PROTO_IP6)); + FIB_PROTOCOL_IP6); dpo_set (&sr_policy->bsid_dpo, DPO_LOAD_BALANCE, DPO_PROTO_IP6, load_balance_create (0, DPO_PROTO_IP6, fhc)); @@ -876,6 +886,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, rv = sr_policy_add (&bsid, segments, weight, (is_spray ? SR_POLICY_TYPE_SPRAY : SR_POLICY_TYPE_DEFAULT), fib_table, is_encap); + vec_free (segments); } else if (is_del) rv = sr_policy_del ((sr_policy_index != (u32) ~ 0 ? NULL : &bsid), @@ -893,6 +904,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input, rv = sr_policy_mod ((sr_policy_index != (u32) ~ 0 ? NULL : &bsid), sr_policy_index, fib_table, operation, segments, sl_index, weight); + vec_free (segments); } switch (rv) @@ -1326,8 +1338,13 @@ encaps_processing_v4 (vlib_node_runtime_t * node, ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (0 | ((6 & 0xF) << 28) | ((ip0_encap->tos & 0xFF) << 20)); - sr0 = (void *) (ip0 + 1); - sr0->protocol = IP_PROTOCOL_IP_IN_IP; + if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE) + { + sr0 = (void *) (ip0 + 1); + sr0->protocol = IP_PROTOCOL_IP_IN_IP; + } + else + ip0->protocol = IP_PROTOCOL_IP_IN_IP; } /** @@ -1810,13 +1827,37 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node, ip3->payload_length = clib_host_to_net_u16 (b3->current_length - sizeof (ip6_header_t)); - sr0 = (void *) (ip0 + 1); - sr1 = (void *) (ip1 + 1); - sr2 = (void *) (ip2 + 1); - sr3 = (void *) (ip3 + 1); + if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE) + { + sr0 = (void *) (ip0 + 1); + sr0->protocol = IP_PROTOCOL_IP6_NONXT; + } + else + ip0->protocol = IP_PROTOCOL_IP6_NONXT; + + if (ip1->protocol == IP_PROTOCOL_IPV6_ROUTE) + { + sr1 = (void *) (ip1 + 1); + sr1->protocol = IP_PROTOCOL_IP6_NONXT; + } + else + ip1->protocol = IP_PROTOCOL_IP6_NONXT; + + if (ip2->protocol == IP_PROTOCOL_IPV6_ROUTE) + { + sr2 = (void *) (ip2 + 1); + sr2->protocol = IP_PROTOCOL_IP6_NONXT; + } + else + ip2->protocol = IP_PROTOCOL_IP6_NONXT; - sr0->protocol = sr1->protocol = sr2->protocol = sr3->protocol = - IP_PROTOCOL_IP6_NONXT; + if (ip3->protocol == IP_PROTOCOL_IPV6_ROUTE) + { + sr3 = (void *) (ip3 + 1); + sr3->protocol = IP_PROTOCOL_IP6_NONXT; + } + else + ip3->protocol = IP_PROTOCOL_IP6_NONXT; /* Which Traffic class and flow label do I set ? */ //ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32(0|((6&0xF)<<28)|((ip0_encap->tos&0xFF)<<20)); @@ -1924,8 +1965,13 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node, ip0->payload_length = clib_host_to_net_u16 (b0->current_length - sizeof (ip6_header_t)); - sr0 = (void *) (ip0 + 1); - sr0->protocol = IP_PROTOCOL_IP6_NONXT; + if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE) + { + sr0 = (void *) (ip0 + 1); + sr0->protocol = IP_PROTOCOL_IP6_NONXT; + } + else + ip0->protocol = IP_PROTOCOL_IP6_NONXT; if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))