@@ -828,11 +828,18 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
}
break;
}
- case OVS_ACTION_ATTR_DECAP_NSH:
- DP_PACKET_BATCH_FOR_EACH (packet, batch) {
- decap_nsh(packet);
+ case OVS_ACTION_ATTR_DECAP_NSH: {
+ size_t i, num = batch->count;
+
+ DP_PACKET_BATCH_REFILL_FOR_EACH (i, num, packet, batch) {
+ if (decap_nsh(packet)) {
+ dp_packet_batch_refill(batch, packet, i);
+ } else {
+ dp_packet_delete(packet);
+ }
}
break;
+ }
case OVS_ACTION_ATTR_OUTPUT:
case OVS_ACTION_ATTR_TUNNEL_PUSH:
@@ -419,6 +419,9 @@ encap_nsh(struct dp_packet *packet, const struct ovs_action_encap_nsh *encap)
case PT_IPV6:
next_proto = NSH_P_IPV6;
break;
+ case PT_NSH:
+ next_proto = NSH_P_NSH;
+ break;
default:
OVS_NOT_REACHED();
}
@@ -444,7 +447,7 @@ encap_nsh(struct dp_packet *packet, const struct ovs_action_encap_nsh *encap)
packet->l3_ofs = 0;
}
-void
+bool
decap_nsh(struct dp_packet *packet)
{
struct nsh_hdr *nsh = (struct nsh_hdr *) dp_packet_l3(packet);
@@ -462,8 +465,12 @@ decap_nsh(struct dp_packet *packet)
case NSH_P_IPV6:
next_pt = PT_IPV6;
break;
+ case NSH_P_NSH:
+ next_pt = PT_NSH;
+ break;
default:
- OVS_NOT_REACHED();
+ /* Unknown inner packet type. Drop packet. */
+ return false;
}
length = nsh_hdr_len(nsh);
@@ -471,6 +478,7 @@ decap_nsh(struct dp_packet *packet)
packet->packet_type = htonl(next_pt);
/* Packet must be recirculated for further processing. */
}
+ return true;
}
/* Converts hex digits in 'hex' to an Ethernet packet in '*packetp'. The
@@ -409,7 +409,7 @@ void pop_eth(struct dp_packet *packet);
void encap_nsh(struct dp_packet *packet,
const struct ovs_action_encap_nsh *encap_nsh);
-void decap_nsh(struct dp_packet *packet);
+bool decap_nsh(struct dp_packet *packet);
#define LLC_DSAP_SNAP 0xaa
#define LLC_SSAP_SNAP 0xaa