actions.c (396665e8320987ff43b20a62a6a1cdae57aa1cc1) actions.c (b2d0f5d5dc53532e6f07bc546a476a55ebdfe0f3)
1/*
2 * Copyright (c) 2007-2017 Nicira, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 29 unchanged lines hidden (view full) ---

38#include <net/dsfield.h>
39#include <net/mpls.h>
40#include <net/sctp/checksum.h>
41
42#include "datapath.h"
43#include "flow.h"
44#include "conntrack.h"
45#include "vport.h"
1/*
2 * Copyright (c) 2007-2017 Nicira, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 29 unchanged lines hidden (view full) ---

38#include <net/dsfield.h>
39#include <net/mpls.h>
40#include <net/sctp/checksum.h>
41
42#include "datapath.h"
43#include "flow.h"
44#include "conntrack.h"
45#include "vport.h"
46#include "flow_netlink.h"
46
47struct deferred_action {
48 struct sk_buff *skb;
49 const struct nlattr *actions;
50 int actions_len;
51
52 /* Store pkt_key clone when creating deferred action. */
53 struct sw_flow_key pkt_key;

--- 321 unchanged lines hidden (view full) ---

375 skb_postpush_rcsum(skb, hdr, ETH_HLEN);
376
377 /* safe right before invalidate_flow_key */
378 key->mac_proto = MAC_PROTO_ETHERNET;
379 invalidate_flow_key(key);
380 return 0;
381}
382
47
48struct deferred_action {
49 struct sk_buff *skb;
50 const struct nlattr *actions;
51 int actions_len;
52
53 /* Store pkt_key clone when creating deferred action. */
54 struct sw_flow_key pkt_key;

--- 321 unchanged lines hidden (view full) ---

376 skb_postpush_rcsum(skb, hdr, ETH_HLEN);
377
378 /* safe right before invalidate_flow_key */
379 key->mac_proto = MAC_PROTO_ETHERNET;
380 invalidate_flow_key(key);
381 return 0;
382}
383
384static int push_nsh(struct sk_buff *skb, struct sw_flow_key *key,
385 const struct nshhdr *nh)
386{
387 int err;
388
389 err = nsh_push(skb, nh);
390 if (err)
391 return err;
392
393 /* safe right before invalidate_flow_key */
394 key->mac_proto = MAC_PROTO_NONE;
395 invalidate_flow_key(key);
396 return 0;
397}
398
399static int pop_nsh(struct sk_buff *skb, struct sw_flow_key *key)
400{
401 int err;
402
403 err = nsh_pop(skb);
404 if (err)
405 return err;
406
407 /* safe right before invalidate_flow_key */
408 if (skb->protocol == htons(ETH_P_TEB))
409 key->mac_proto = MAC_PROTO_ETHERNET;
410 else
411 key->mac_proto = MAC_PROTO_NONE;
412 invalidate_flow_key(key);
413 return 0;
414}
415
383static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
384 __be32 addr, __be32 new_addr)
385{
386 int transport_len = skb->len - skb_transport_offset(skb);
387
388 if (nh->frag_off & htons(IP_OFFSET))
389 return;
390

--- 206 unchanged lines hidden (view full) ---

597 if (mask->ipv6_hlimit) {
598 OVS_SET_MASKED(nh->hop_limit, key->ipv6_hlimit,
599 mask->ipv6_hlimit);
600 flow_key->ip.ttl = nh->hop_limit;
601 }
602 return 0;
603}
604
416static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
417 __be32 addr, __be32 new_addr)
418{
419 int transport_len = skb->len - skb_transport_offset(skb);
420
421 if (nh->frag_off & htons(IP_OFFSET))
422 return;
423

--- 206 unchanged lines hidden (view full) ---

630 if (mask->ipv6_hlimit) {
631 OVS_SET_MASKED(nh->hop_limit, key->ipv6_hlimit,
632 mask->ipv6_hlimit);
633 flow_key->ip.ttl = nh->hop_limit;
634 }
635 return 0;
636}
637
638static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
639 const struct nlattr *a)
640{
641 struct nshhdr *nh;
642 size_t length;
643 int err;
644 u8 flags;
645 u8 ttl;
646 int i;
647
648 struct ovs_key_nsh key;
649 struct ovs_key_nsh mask;
650
651 err = nsh_key_from_nlattr(a, &key, &mask);
652 if (err)
653 return err;
654
655 /* Make sure the NSH base header is there */
656 if (!pskb_may_pull(skb, skb_network_offset(skb) + NSH_BASE_HDR_LEN))
657 return -ENOMEM;
658
659 nh = nsh_hdr(skb);
660 length = nsh_hdr_len(nh);
661
662 /* Make sure the whole NSH header is there */
663 err = skb_ensure_writable(skb, skb_network_offset(skb) +
664 length);
665 if (unlikely(err))
666 return err;
667
668 nh = nsh_hdr(skb);
669 skb_postpull_rcsum(skb, nh, length);
670 flags = nsh_get_flags(nh);
671 flags = OVS_MASKED(flags, key.base.flags, mask.base.flags);
672 flow_key->nsh.base.flags = flags;
673 ttl = nsh_get_ttl(nh);
674 ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl);
675 flow_key->nsh.base.ttl = ttl;
676 nsh_set_flags_and_ttl(nh, flags, ttl);
677 nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr,
678 mask.base.path_hdr);
679 flow_key->nsh.base.path_hdr = nh->path_hdr;
680 switch (nh->mdtype) {
681 case NSH_M_TYPE1:
682 for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
683 nh->md1.context[i] =
684 OVS_MASKED(nh->md1.context[i], key.context[i],
685 mask.context[i]);
686 }
687 memcpy(flow_key->nsh.context, nh->md1.context,
688 sizeof(nh->md1.context));
689 break;
690 case NSH_M_TYPE2:
691 memset(flow_key->nsh.context, 0,
692 sizeof(flow_key->nsh.context));
693 break;
694 default:
695 return -EINVAL;
696 }
697 skb_postpush_rcsum(skb, nh, length);
698 return 0;
699}
700
605/* Must follow skb_ensure_writable() since that can move the skb data. */
606static void set_tp_port(struct sk_buff *skb, __be16 *port,
607 __be16 new_port, __sum16 *check)
608{
609 inet_proto_csum_replace2(check, skb, *port, new_port, false);
610 *port = new_port;
611}
612

--- 406 unchanged lines hidden (view full) ---

1019 err = -EINVAL;
1020 break;
1021
1022 case OVS_KEY_ATTR_ETHERNET:
1023 err = set_eth_addr(skb, flow_key, nla_data(a),
1024 get_mask(a, struct ovs_key_ethernet *));
1025 break;
1026
701/* Must follow skb_ensure_writable() since that can move the skb data. */
702static void set_tp_port(struct sk_buff *skb, __be16 *port,
703 __be16 new_port, __sum16 *check)
704{
705 inet_proto_csum_replace2(check, skb, *port, new_port, false);
706 *port = new_port;
707}
708

--- 406 unchanged lines hidden (view full) ---

1115 err = -EINVAL;
1116 break;
1117
1118 case OVS_KEY_ATTR_ETHERNET:
1119 err = set_eth_addr(skb, flow_key, nla_data(a),
1120 get_mask(a, struct ovs_key_ethernet *));
1121 break;
1122
1123 case OVS_KEY_ATTR_NSH:
1124 err = set_nsh(skb, flow_key, a);
1125 break;
1126
1027 case OVS_KEY_ATTR_IPV4:
1028 err = set_ipv4(skb, flow_key, nla_data(a),
1029 get_mask(a, struct ovs_key_ipv4 *));
1030 break;
1031
1032 case OVS_KEY_ATTR_IPV6:
1033 err = set_ipv6(skb, flow_key, nla_data(a),
1034 get_mask(a, struct ovs_key_ipv6 *));

--- 174 unchanged lines hidden (view full) ---

1209
1210 case OVS_ACTION_ATTR_PUSH_ETH:
1211 err = push_eth(skb, key, nla_data(a));
1212 break;
1213
1214 case OVS_ACTION_ATTR_POP_ETH:
1215 err = pop_eth(skb, key);
1216 break;
1127 case OVS_KEY_ATTR_IPV4:
1128 err = set_ipv4(skb, flow_key, nla_data(a),
1129 get_mask(a, struct ovs_key_ipv4 *));
1130 break;
1131
1132 case OVS_KEY_ATTR_IPV6:
1133 err = set_ipv6(skb, flow_key, nla_data(a),
1134 get_mask(a, struct ovs_key_ipv6 *));

--- 174 unchanged lines hidden (view full) ---

1309
1310 case OVS_ACTION_ATTR_PUSH_ETH:
1311 err = push_eth(skb, key, nla_data(a));
1312 break;
1313
1314 case OVS_ACTION_ATTR_POP_ETH:
1315 err = pop_eth(skb, key);
1316 break;
1317
1318 case OVS_ACTION_ATTR_PUSH_NSH: {
1319 u8 buffer[NSH_HDR_MAX_LEN];
1320 struct nshhdr *nh = (struct nshhdr *)buffer;
1321
1322 err = nsh_hdr_from_nlattr(nla_data(a), nh,
1323 NSH_HDR_MAX_LEN);
1324 if (unlikely(err))
1325 break;
1326 err = push_nsh(skb, key, nh);
1327 break;
1217 }
1218
1328 }
1329
1330 case OVS_ACTION_ATTR_POP_NSH:
1331 err = pop_nsh(skb, key);
1332 break;
1333 }
1334
1219 if (unlikely(err)) {
1220 kfree_skb(skb);
1221 return err;
1222 }
1223 }
1224
1225 consume_skb(skb);
1226 return 0;

--- 149 unchanged lines hidden ---
1335 if (unlikely(err)) {
1336 kfree_skb(skb);
1337 return err;
1338 }
1339 }
1340
1341 consume_skb(skb);
1342 return 0;

--- 149 unchanged lines hidden ---