- ip4_header_t * ip0 = vlib_buffer_get_current(b0);
- ip4_header_t * ip1 = vlib_buffer_get_current(b1);
- ip4_header_t * ip2 = vlib_buffer_get_current(b2);
- ip4_header_t * ip3 = vlib_buffer_get_current(b3);
- u32 checksum0;
- u32 checksum1;
- u32 checksum2;
- u32 checksum3;
-
- checksum0 = ip0->checksum + clib_host_to_net_u16 (0x0100);
- checksum1 = ip1->checksum + clib_host_to_net_u16 (0x0100);
- checksum2 = ip2->checksum + clib_host_to_net_u16 (0x0100);
- checksum3 = ip3->checksum + clib_host_to_net_u16 (0x0100);
-
- checksum0 += checksum0 >= 0xffff;
- checksum1 += checksum1 >= 0xffff;
- checksum2 += checksum2 >= 0xffff;
- checksum3 += checksum3 >= 0xffff;
-
- ip0->checksum = checksum0;
- ip1->checksum = checksum1;
- ip2->checksum = checksum2;
- ip3->checksum = checksum3;
-
- ip0->ttl -= 1;
- ip1->ttl -= 1;
- ip2->ttl -= 1;
- ip3->ttl -= 1;
-
- ttl1 = ip1->ttl;
- ttl0 = ip0->ttl;
- ttl3 = ip3->ttl;
- ttl2 = ip2->ttl;
- }
- else if (payload_is_ip6)
- {
- /*
- * decrement the TTL on ingress to the LSP
- */
- ip6_header_t * ip0 = vlib_buffer_get_current(b0);
- ip6_header_t * ip1 = vlib_buffer_get_current(b1);
- ip6_header_t * ip2 = vlib_buffer_get_current(b2);
- ip6_header_t * ip3 = vlib_buffer_get_current(b3);
-
- ip0->hop_limit -= 1;
- ip1->hop_limit -= 1;
- ip2->hop_limit -= 1;
- ip3->hop_limit -= 1;
-
- ttl0 = ip0->hop_limit;
- ttl1 = ip1->hop_limit;
- ttl2 = ip2->hop_limit;
- ttl3 = ip3->hop_limit;
- }
- else if (payload_is_ethernet)
- {
+ if (DPO_PROTO_IP4 == dproto)
+ {
+ ip4_header_t * ip0 = vlib_buffer_get_current(b0);
+ ip4_header_t * ip1 = vlib_buffer_get_current(b1);
+ ip4_header_t * ip2 = vlib_buffer_get_current(b2);
+ ip4_header_t * ip3 = vlib_buffer_get_current(b3);
+
+ if (!(MPLS_LABEL_DPO_FLAG_NO_IP_TTL_DECR & flags))
+ {
+ /*
+ * decrement the TTL on ingress to the LSP
+ */
+ u32 checksum0;
+ u32 checksum1;
+ u32 checksum2;
+ u32 checksum3;
+
+ checksum0 = ip0->checksum + clib_host_to_net_u16 (0x0100);
+ checksum1 = ip1->checksum + clib_host_to_net_u16 (0x0100);
+ checksum2 = ip2->checksum + clib_host_to_net_u16 (0x0100);
+ checksum3 = ip3->checksum + clib_host_to_net_u16 (0x0100);
+
+ checksum0 += checksum0 >= 0xffff;
+ checksum1 += checksum1 >= 0xffff;
+ checksum2 += checksum2 >= 0xffff;
+ checksum3 += checksum3 >= 0xffff;
+
+ ip0->checksum = checksum0;
+ ip1->checksum = checksum1;
+ ip2->checksum = checksum2;
+ ip3->checksum = checksum3;
+
+ ip0->ttl -= 1;
+ ip1->ttl -= 1;
+ ip2->ttl -= 1;
+ ip3->ttl -= 1;
+ }
+
+ if (flags & MPLS_LABEL_DPO_FLAG_UNIFORM_MODE)
+ {
+ ttl1 = ip1->ttl;
+ ttl0 = ip0->ttl;
+ ttl3 = ip3->ttl;
+ ttl2 = ip2->ttl;
+ /* by default copy the 3 most significant bits */
+ exp0 = ip_dscp_to_mpls_exp(ip0->tos);
+ exp1 = ip_dscp_to_mpls_exp(ip1->tos);
+ exp2 = ip_dscp_to_mpls_exp(ip2->tos);
+ exp3 = ip_dscp_to_mpls_exp(ip3->tos);
+ }
+
+ /* save the payload proto information in mpls opaque */
+ vnet_buffer(b0)->mpls.pyld_proto = DPO_PROTO_IP4;
+ vnet_buffer(b1)->mpls.pyld_proto = DPO_PROTO_IP4;
+ vnet_buffer(b2)->mpls.pyld_proto = DPO_PROTO_IP4;
+ vnet_buffer(b3)->mpls.pyld_proto = DPO_PROTO_IP4;
+ }
+ else if (DPO_PROTO_IP6 == dproto)
+ {
+ /*
+ * decrement the TTL on ingress to the LSP
+ */
+ ip6_header_t * ip0 = vlib_buffer_get_current(b0);
+ ip6_header_t * ip1 = vlib_buffer_get_current(b1);
+ ip6_header_t * ip2 = vlib_buffer_get_current(b2);
+ ip6_header_t * ip3 = vlib_buffer_get_current(b3);
+
+ if (!(MPLS_LABEL_DPO_FLAG_NO_IP_TTL_DECR & flags))
+ {
+ ip0->hop_limit -= 1;
+ ip1->hop_limit -= 1;
+ ip2->hop_limit -= 1;
+ ip3->hop_limit -= 1;
+ }
+ if (flags & MPLS_LABEL_DPO_FLAG_UNIFORM_MODE)
+ {
+ ttl0 = ip0->hop_limit;
+ ttl1 = ip1->hop_limit;
+ ttl2 = ip2->hop_limit;
+ ttl3 = ip3->hop_limit;
+ /* by default copy the 3 most significant bits */
+ exp0 = ip_dscp_to_mpls_exp(
+ ip6_traffic_class_network_order(ip0));
+ exp1 = ip_dscp_to_mpls_exp(
+ ip6_traffic_class_network_order(ip1));
+ exp2 = ip_dscp_to_mpls_exp(
+ ip6_traffic_class_network_order(ip2));
+ exp3 = ip_dscp_to_mpls_exp(
+ ip6_traffic_class_network_order(ip3));
+ }
+
+ /* save the payload proto information in mpls opaque */
+ vnet_buffer(b0)->mpls.pyld_proto = DPO_PROTO_IP6;
+ vnet_buffer(b1)->mpls.pyld_proto = DPO_PROTO_IP6;
+ vnet_buffer(b2)->mpls.pyld_proto = DPO_PROTO_IP6;
+ vnet_buffer(b3)->mpls.pyld_proto = DPO_PROTO_IP6;
+ }
+ else
+ {
+ /*
+ * nothing to change in the ethernet header
+ */
+ ttl0 = ttl1 = ttl2 = ttl3 = MPLS_LABEL_DEFAULT_TTL;
+ exp0 = exp1 = exp2 = exp3 = MPLS_LABEL_DEFAULT_EXP;
+ }