Make dpif_close() accept a null pointer.
[sliver-openvswitch.git] / datapath / dp_act.c
1 /*
2  * Distributed under the terms of the GNU GPL version 2.
3  * Copyright (c) 2007, 2008 The Board of Trustees of The Leland 
4  * Stanford Junior University
5  */
6
7 /* Functions for executing OpenFlow actions. */
8
9 #include <linux/skbuff.h>
10 #include <linux/in.h>
11 #include <linux/ip.h>
12 #include <linux/tcp.h>
13 #include <linux/udp.h>
14 #include <linux/in6.h>
15 #include <linux/if_vlan.h>
16 #include <net/checksum.h>
17 #include "forward.h"
18 #include "dp_act.h"
19 #include "openflow/nicira-ext.h"
20 #include "nx_act.h"
21
22
23 static uint16_t
24 validate_output(struct datapath *dp, const struct sw_flow_key *key, 
25                 const struct ofp_action_header *ah) 
26 {
27         struct ofp_action_output *oa = (struct ofp_action_output *)ah;
28
29         if (oa->port == htons(OFPP_NONE) || oa->port == key->in_port)
30                 return OFPBAC_BAD_OUT_PORT;
31
32         return ACT_VALIDATION_OK;
33 }
34
35 static int 
36 do_output(struct datapath *dp, struct sk_buff *skb, size_t max_len,
37                 int out_port, int ignore_no_fwd)
38 {
39         if (!skb)
40                 return -ENOMEM;
41         return (likely(out_port != OFPP_CONTROLLER)
42                 ? dp_output_port(dp, skb, out_port, ignore_no_fwd)
43                 : dp_output_control(dp, skb, fwd_save_skb(skb),
44                                          max_len, OFPR_ACTION));
45 }
46
47
48 static struct sk_buff *
49 vlan_pull_tag(struct sk_buff *skb)
50 {
51         struct vlan_ethhdr *vh = vlan_eth_hdr(skb);
52         struct ethhdr *eh;
53
54
55         /* Verify we were given a vlan packet */
56         if (vh->h_vlan_proto != htons(ETH_P_8021Q))
57                 return skb;
58
59         memmove(skb->data + VLAN_HLEN, skb->data, 2 * VLAN_ETH_ALEN);
60
61         eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
62
63         skb->protocol = eh->h_proto;
64         skb->mac_header += VLAN_HLEN;
65
66         return skb;
67 }
68
69
70 static struct sk_buff *
71 modify_vlan_tci(struct sk_buff *skb, struct sw_flow_key *key, 
72                 uint16_t tci, uint16_t mask)
73 {
74         struct vlan_ethhdr *vh = vlan_eth_hdr(skb);
75
76         if (key->dl_vlan != htons(OFP_VLAN_NONE)) {
77                 /* Modify vlan id, but maintain other TCI values */
78                 vh->h_vlan_TCI = (vh->h_vlan_TCI & ~(htons(mask))) | htons(tci);
79         } else  {
80                 /* Add vlan header */
81
82                 /* xxx The vlan_put_tag function, doesn't seem to work
83                  * xxx reliably when it attempts to use the hardware-accelerated
84                  * xxx version.  We'll directly use the software version
85                  * xxx until the problem can be diagnosed.
86                  */
87                 skb = __vlan_put_tag(skb, tci);
88                 vh = vlan_eth_hdr(skb);
89         }
90         key->dl_vlan = vh->h_vlan_TCI & htons(VLAN_VID_MASK);
91
92         return skb;
93 }
94
95 static struct sk_buff *
96 set_vlan_vid(struct sk_buff *skb, struct sw_flow_key *key, 
97                 const struct ofp_action_header *ah)
98 {
99         struct ofp_action_vlan_vid *va = (struct ofp_action_vlan_vid *)ah;
100         uint16_t tci = ntohs(va->vlan_vid);
101
102         return modify_vlan_tci(skb, key, tci, VLAN_VID_MASK);
103 }
104
105 /* Mask for the priority bits in a vlan header.  The kernel doesn't
106  * define this like it does for VID. */
107 #define VLAN_PCP_MASK 0xe000
108
109 static struct sk_buff *
110 set_vlan_pcp(struct sk_buff *skb, struct sw_flow_key *key, 
111                 const struct ofp_action_header *ah)
112 {
113         struct ofp_action_vlan_pcp *va = (struct ofp_action_vlan_pcp *)ah;
114         uint16_t tci = (uint16_t)va->vlan_pcp << 13;
115
116         return modify_vlan_tci(skb, key, tci, VLAN_PCP_MASK);
117 }
118
119 static struct sk_buff *
120 strip_vlan(struct sk_buff *skb, struct sw_flow_key *key, 
121                 const struct ofp_action_header *ah)
122 {
123         vlan_pull_tag(skb);
124         key->dl_vlan = htons(OFP_VLAN_NONE);
125
126         return skb;
127 }
128
129 static struct sk_buff *
130 set_dl_addr(struct sk_buff *skb, struct sw_flow_key *key, 
131                 const struct ofp_action_header *ah)
132 {
133         struct ofp_action_dl_addr *da = (struct ofp_action_dl_addr *)ah;
134         struct ethhdr *eh = eth_hdr(skb);
135
136         if (da->type == htons(OFPAT_SET_DL_SRC))
137                 memcpy(eh->h_source, da->dl_addr, sizeof eh->h_source);
138         else 
139                 memcpy(eh->h_dest, da->dl_addr, sizeof eh->h_dest);
140
141         return skb;
142 }
143
144 /* Updates 'sum', which is a field in 'skb''s data, given that a 4-byte field
145  * covered by the sum has been changed from 'from' to 'to'.  If set,
146  * 'pseudohdr' indicates that the field is in the TCP or UDP pseudo-header.
147  * Based on nf_proto_csum_replace4. */
148 static void update_csum(__sum16 *sum, struct sk_buff *skb,
149                         __be32 from, __be32 to, int pseudohdr)
150 {
151         __be32 diff[] = { ~from, to };
152         if (skb->ip_summed != CHECKSUM_PARTIAL) {
153                 *sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
154                                 ~csum_unfold(*sum)));
155                 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
156                         skb->csum = ~csum_partial((char *)diff, sizeof(diff),
157                                                 ~skb->csum);
158         } else if (pseudohdr)
159                 *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff),
160                                 csum_unfold(*sum)));
161 }
162
163 static struct sk_buff * 
164 set_nw_addr(struct sk_buff *skb, struct sw_flow_key *key, 
165                 const struct ofp_action_header *ah)
166 {
167         struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
168         uint16_t eth_proto = ntohs(key->dl_type);
169
170         if (eth_proto == ETH_P_IP) {
171                 struct iphdr *nh = ip_hdr(skb);
172                 uint32_t new, *field;
173
174                 new = na->nw_addr;
175
176                 if (ah->type == htons(OFPAT_SET_NW_SRC))
177                         field = &nh->saddr;
178                 else
179                         field = &nh->daddr;
180
181                 if (key->nw_proto == IPPROTO_TCP) {
182                         struct tcphdr *th = tcp_hdr(skb);
183                         update_csum(&th->check, skb, *field, new, 1);
184                 } else if (key->nw_proto == IPPROTO_UDP) {
185                         struct udphdr *th = udp_hdr(skb);
186                         update_csum(&th->check, skb, *field, new, 1);
187                 }
188                 update_csum(&nh->check, skb, *field, new, 0);
189                 *field = new;
190         }
191
192         return skb;
193 }
194
195 static struct sk_buff *
196 set_tp_port(struct sk_buff *skb, struct sw_flow_key *key, 
197                 const struct ofp_action_header *ah)
198 {
199         struct ofp_action_tp_port *ta = (struct ofp_action_tp_port *)ah;
200         uint16_t eth_proto = ntohs(key->dl_type);
201
202         if (eth_proto == ETH_P_IP) {
203                 uint16_t new, *field;
204
205                 new = ta->tp_port;
206
207                 if (key->nw_proto == IPPROTO_TCP) {
208                         struct tcphdr *th = tcp_hdr(skb);
209
210                         if (ah->type == htons(OFPAT_SET_TP_SRC))
211                                 field = &th->source;
212                         else
213                                 field = &th->dest;
214
215                         update_csum(&th->check, skb, *field, new, 1);
216                         *field = new;
217                 } else if (key->nw_proto == IPPROTO_UDP) {
218                         struct udphdr *th = udp_hdr(skb);
219
220                         if (ah->type == htons(OFPAT_SET_TP_SRC))
221                                 field = &th->source;
222                         else
223                                 field = &th->dest;
224
225                         update_csum(&th->check, skb, *field, new, 1);
226                         *field = new;
227                 }
228         }
229
230         return skb;
231 }
232
233 struct openflow_action {
234         size_t min_size;
235         size_t max_size;
236         uint16_t (*validate)(struct datapath *dp, 
237                         const struct sw_flow_key *key,
238                         const struct ofp_action_header *ah);
239         struct sk_buff *(*execute)(struct sk_buff *skb, 
240                         struct sw_flow_key *key, 
241                         const struct ofp_action_header *ah);
242 };
243
244 static const struct openflow_action of_actions[] = {
245         [OFPAT_OUTPUT] = {
246                 sizeof(struct ofp_action_output),
247                 sizeof(struct ofp_action_output),
248                 validate_output,
249                 NULL                   /* This is optimized into execute_actions */
250         },
251         [OFPAT_SET_VLAN_VID] = {
252                 sizeof(struct ofp_action_vlan_vid),
253                 sizeof(struct ofp_action_vlan_vid),
254                 NULL,
255                 set_vlan_vid
256         },
257         [OFPAT_SET_VLAN_PCP] = {
258                 sizeof(struct ofp_action_vlan_pcp),
259                 sizeof(struct ofp_action_vlan_pcp),
260                 NULL,
261                 set_vlan_pcp
262         },
263         [OFPAT_STRIP_VLAN] = {
264                 sizeof(struct ofp_action_header),
265                 sizeof(struct ofp_action_header),
266                 NULL,
267                 strip_vlan
268         },
269         [OFPAT_SET_DL_SRC] = {
270                 sizeof(struct ofp_action_dl_addr),
271                 sizeof(struct ofp_action_dl_addr),
272                 NULL,
273                 set_dl_addr
274         },
275         [OFPAT_SET_DL_DST] = {
276                 sizeof(struct ofp_action_dl_addr),
277                 sizeof(struct ofp_action_dl_addr),
278                 NULL,
279                 set_dl_addr
280         },
281         [OFPAT_SET_NW_SRC] = {
282                 sizeof(struct ofp_action_nw_addr),
283                 sizeof(struct ofp_action_nw_addr),
284                 NULL,
285                 set_nw_addr
286         },
287         [OFPAT_SET_NW_DST] = {
288                 sizeof(struct ofp_action_nw_addr),
289                 sizeof(struct ofp_action_nw_addr),
290                 NULL,
291                 set_nw_addr
292         },
293         [OFPAT_SET_TP_SRC] = {
294                 sizeof(struct ofp_action_tp_port),
295                 sizeof(struct ofp_action_tp_port),
296                 NULL,
297                 set_tp_port
298         },
299         [OFPAT_SET_TP_DST] = {
300                 sizeof(struct ofp_action_tp_port),
301                 sizeof(struct ofp_action_tp_port),
302                 NULL,
303                 set_tp_port
304         }
305         /* OFPAT_VENDOR is not here, since it would blow up the array size. */
306 };
307
308 /* Validate built-in OpenFlow actions.  Either returns ACT_VALIDATION_OK
309  * or an OFPET_BAD_ACTION error code. */
310 static uint16_t 
311 validate_ofpat(struct datapath *dp, const struct sw_flow_key *key, 
312                 const struct ofp_action_header *ah, uint16_t type, uint16_t len)
313 {
314         int ret = ACT_VALIDATION_OK;
315         const struct openflow_action *act = &of_actions[type];
316
317         if ((len < act->min_size) || (len > act->max_size)) 
318                 return OFPBAC_BAD_LEN;
319
320         if (act->validate) 
321                 ret = act->validate(dp, key, ah);
322
323         return ret;
324 }
325
326 /* Validate vendor-defined actions.  Either returns ACT_VALIDATION_OK
327  * or an OFPET_BAD_ACTION error code. */
328 static uint16_t 
329 validate_vendor(struct datapath *dp, const struct sw_flow_key *key, 
330                 const struct ofp_action_header *ah, uint16_t len)
331 {
332         struct ofp_action_vendor_header *avh;
333         int ret = ACT_VALIDATION_OK;
334
335         if (len < sizeof(struct ofp_action_vendor_header))
336                 return OFPBAC_BAD_LEN;
337
338         avh = (struct ofp_action_vendor_header *)ah;
339
340         switch(ntohl(avh->vendor)) {
341         case NX_VENDOR_ID: 
342                 ret = nx_validate_act(dp, key, (struct nx_action_header *)avh, len);
343                 break;
344
345         default:
346                 return OFPBAC_BAD_VENDOR;
347         }
348
349         return ret;
350 }
351
352 /* Validates a list of actions.  If a problem is found, a code for the
353  * OFPET_BAD_ACTION error type is returned.  If the action list validates, 
354  * ACT_VALIDATION_OK is returned. */
355 uint16_t 
356 validate_actions(struct datapath *dp, const struct sw_flow_key *key,
357                 const struct ofp_action_header *actions, size_t actions_len)
358 {
359         uint8_t *p = (uint8_t *)actions;
360         int err;
361
362         while (actions_len >= sizeof(struct ofp_action_header)) {
363                 struct ofp_action_header *ah = (struct ofp_action_header *)p;
364                 size_t len = ntohs(ah->len);
365                 uint16_t type;
366
367                 /* Make there's enough remaining data for the specified length
368                  * and that the action length is a multiple of 64 bits. */
369                 if ((actions_len < len) || (len % 8) != 0)
370                         return OFPBAC_BAD_LEN;
371
372                 type = ntohs(ah->type);
373                 if (type < ARRAY_SIZE(of_actions)) {
374                         err = validate_ofpat(dp, key, ah, type, len);
375                         if (err != ACT_VALIDATION_OK)
376                                 return err;
377                 } else if (type == OFPAT_VENDOR) {
378                         err = validate_vendor(dp, key, ah, len);
379                         if (err != ACT_VALIDATION_OK)
380                                 return err;
381                 } else 
382                         return OFPBAC_BAD_TYPE;
383
384                 p += len;
385                 actions_len -= len;
386         }
387
388         /* Check if there's any trailing garbage. */
389         if (actions_len != 0) 
390                 return OFPBAC_BAD_LEN;
391
392         return ACT_VALIDATION_OK;
393 }
394
395 /* Execute a built-in OpenFlow action against 'skb'. */
396 static struct sk_buff *
397 execute_ofpat(struct sk_buff *skb, struct sw_flow_key *key, 
398                 const struct ofp_action_header *ah, uint16_t type)
399 {
400         const struct openflow_action *act = &of_actions[type];
401
402         if (act->execute)  {
403                 if (!make_writable(&skb)) {
404                         if (net_ratelimit())
405                                 printk("make_writable failed\n");
406                         return skb;
407                 }
408                 skb = act->execute(skb, key, ah);
409         }
410
411         return skb;
412 }
413
414 /* Execute a vendor-defined action against 'skb'. */
415 static struct sk_buff *
416 execute_vendor(struct sk_buff *skb, const struct sw_flow_key *key, 
417                 const struct ofp_action_header *ah)
418 {
419         struct ofp_action_vendor_header *avh 
420                         = (struct ofp_action_vendor_header *)ah;
421
422         /* NB: If changes need to be made to the packet, a call should be
423          * made to make_writable or its equivalent first. */
424
425         switch(ntohl(avh->vendor)) {
426         case NX_VENDOR_ID: 
427                 skb = nx_execute_act(skb, key, (struct nx_action_header *)avh);
428                 break;
429
430         default:
431                 /* This should not be possible due to prior validation. */
432                 if (net_ratelimit())
433                         printk("attempt to execute action with unknown vendor: %#x\n", 
434                                         ntohl(avh->vendor));
435                 break;
436         }
437
438         return skb;
439 }
440
441 /* Execute a list of actions against 'skb'. */
442 void execute_actions(struct datapath *dp, struct sk_buff *skb,
443                      struct sw_flow_key *key,
444                      const struct ofp_action_header *actions, size_t actions_len,
445                      int ignore_no_fwd)
446 {
447         /* Every output action needs a separate clone of 'skb', but the common
448          * case is just a single output action, so that doing a clone and
449          * then freeing the original skbuff is wasteful.  So the following code
450          * is slightly obscure just to avoid that. */
451         int prev_port;
452         size_t max_len=0;        /* Initialze to make compiler happy */
453         uint8_t *p = (uint8_t *)actions;
454
455         prev_port = -1;
456
457         /* The action list was already validated, so we can be a bit looser
458          * in our sanity-checking. */
459         while (actions_len > 0) {
460                 struct ofp_action_header *ah = (struct ofp_action_header *)p;
461                 size_t len = htons(ah->len);
462
463                 WARN_ON_ONCE(skb_shared(skb));
464                 if (prev_port != -1) {
465                         do_output(dp, skb_clone(skb, GFP_ATOMIC),
466                                   max_len, prev_port, ignore_no_fwd);
467                         prev_port = -1;
468                 }
469
470                 if (likely(ah->type == htons(OFPAT_OUTPUT))) {
471                         struct ofp_action_output *oa = (struct ofp_action_output *)p;
472                         prev_port = ntohs(oa->port);
473                         max_len = ntohs(oa->max_len);
474                 } else {
475                         uint16_t type = ntohs(ah->type);
476
477                         if (type < ARRAY_SIZE(of_actions)) 
478                                 skb = execute_ofpat(skb, key, ah, type);
479                         else if (type == OFPAT_VENDOR) 
480                                 skb = execute_vendor(skb, key, ah);
481
482                         if (!skb) {
483                                 if (net_ratelimit())
484                                         printk("execute_actions lost skb\n");
485                                 return;
486                         }
487                 }
488
489                 p += len;
490                 actions_len -= len;
491         }
492         if (prev_port != -1)
493                 do_output(dp, skb, max_len, prev_port, ignore_no_fwd);
494         else
495                 kfree_skb(skb);
496 }
497
498 /* Utility functions. */
499
500 /* Makes '*pskb' writable, possibly copying it and setting '*pskb' to point to
501  * the copy.
502  * Returns 1 if successful, 0 on failure. */
503 int
504 make_writable(struct sk_buff **pskb)
505 {
506         struct sk_buff *skb = *pskb;
507         if (skb_shared(skb) || skb_cloned(skb)) {
508                 struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
509                 if (!nskb)
510                         return 0;
511                 kfree_skb(skb);
512                 *pskb = nskb;
513                 return 1;
514         } else {
515                 unsigned int hdr_len = (skb_transport_offset(skb)
516                                         + sizeof(struct tcphdr));
517                 return pskb_may_pull(skb, min(hdr_len, skb->len));
518         }
519 }