-static void
-dp_netdev_set_dl_dst(struct ofpbuf *packet, const uint8_t dl_addr[ETH_ADDR_LEN])
-{
- struct eth_header *eh = packet->l2;
- memcpy(eh->eth_dst, dl_addr, sizeof eh->eth_dst);
-}
-
-static bool
-is_ip(const struct ofpbuf *packet, const struct flow *key)
-{
- return key->dl_type == htons(ETH_TYPE_IP) && packet->l4;
-}
-
-static void
-dp_netdev_set_nw_addr(struct ofpbuf *packet, struct flow *key,
- const struct odp_action_nw_addr *a)
-{
- if (is_ip(packet, key)) {
- struct ip_header *nh = packet->l3;
- uint32_t *field;
-
- field = a->type == ODPAT_SET_NW_SRC ? &nh->ip_src : &nh->ip_dst;
- if (key->nw_proto == IP_TYPE_TCP && packet->l7) {
- struct tcp_header *th = packet->l4;
- th->tcp_csum = recalc_csum32(th->tcp_csum, *field, a->nw_addr);
- } else if (key->nw_proto == IP_TYPE_UDP && packet->l7) {
- struct udp_header *uh = packet->l4;
- if (uh->udp_csum) {
- uh->udp_csum = recalc_csum32(uh->udp_csum, *field, a->nw_addr);
- if (!uh->udp_csum) {
- uh->udp_csum = 0xffff;
- }
- }
- }
- nh->ip_csum = recalc_csum32(nh->ip_csum, *field, a->nw_addr);
- *field = a->nw_addr;
- }
-}
-
-static void
-dp_netdev_set_nw_tos(struct ofpbuf *packet, struct flow *key,
- const struct odp_action_nw_tos *a)
-{
- if (is_ip(packet, key)) {
- struct ip_header *nh = packet->l3;
- uint8_t *field = &nh->ip_tos;
-
- /* Set the DSCP bits and preserve the ECN bits. */
- uint8_t new = a->nw_tos | (nh->ip_tos & IP_ECN_MASK);
-
- nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field),
- htons((uint16_t)a->nw_tos));
- *field = new;
- }
-}
-
-static void
-dp_netdev_set_tp_port(struct ofpbuf *packet, struct flow *key,
- const struct odp_action_tp_port *a)
-{
- if (is_ip(packet, key)) {
- uint16_t *field;
- if (key->nw_proto == IPPROTO_TCP && packet->l7) {
- struct tcp_header *th = packet->l4;
- field = a->type == ODPAT_SET_TP_SRC ? &th->tcp_src : &th->tcp_dst;
- th->tcp_csum = recalc_csum16(th->tcp_csum, *field, a->tp_port);
- *field = a->tp_port;
- } else if (key->nw_proto == IPPROTO_UDP && packet->l7) {
- struct udp_header *uh = packet->l4;
- field = a->type == ODPAT_SET_TP_SRC ? &uh->udp_src : &uh->udp_dst;
- uh->udp_csum = recalc_csum16(uh->udp_csum, *field, a->tp_port);
- *field = a->tp_port;
- } else {
- return;
- }
- }