]>
git.proxmox.com Git - mirror_ovs.git/blob - lib/packets.c
2 * Copyright (c) 2009, 2010, 2011 Nicira Networks.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <arpa/inet.h>
21 #include <netinet/in.h>
23 #include "byte-order.h"
24 #include "dynamic-string.h"
27 const struct in6_addr in6addr_exact
= IN6ADDR_EXACT_INIT
;
29 /* Parses 's' as a 16-digit hexadecimal number representing a datapath ID. On
30 * success stores the dpid into '*dpidp' and returns true, on failure stores 0
31 * into '*dpidp' and returns false.
33 * Rejects an all-zeros dpid as invalid. */
35 dpid_from_string(const char *s
, uint64_t *dpidp
)
37 *dpidp
= (strlen(s
) == 16 && strspn(s
, "0123456789abcdefABCDEF") == 16
38 ? strtoull(s
, NULL
, 16)
44 eth_addr_from_string(const char *s
, uint8_t ea
[ETH_ADDR_LEN
])
46 if (sscanf(s
, ETH_ADDR_SCAN_FMT
, ETH_ADDR_SCAN_ARGS(ea
))
47 == ETH_ADDR_SCAN_COUNT
) {
50 memset(ea
, 0, ETH_ADDR_LEN
);
55 /* Fills 'b' with an 802.2 SNAP packet with Ethernet source address 'eth_src',
56 * the Nicira OUI as SNAP organization and 'snap_type' as SNAP type. The text
57 * string in 'tag' is enclosed as the packet payload.
59 * This function is used by Open vSwitch to compose packets in cases where
60 * context is important but content doesn't (or shouldn't) matter. For this
61 * purpose, 'snap_type' should be a random number and 'tag' should be an
62 * English phrase that explains the purpose of the packet. (The English phrase
63 * gives hapless admins running Wireshark the opportunity to figure out what's
66 compose_benign_packet(struct ofpbuf
*b
, const char *tag
, uint16_t snap_type
,
67 const uint8_t eth_src
[ETH_ADDR_LEN
])
69 size_t tag_size
= strlen(tag
) + 1;
72 payload
= snap_compose(b
, eth_addr_broadcast
, eth_src
, 0x002320, snap_type
,
73 tag_size
+ ETH_ADDR_LEN
);
74 memcpy(payload
, tag
, tag_size
);
75 memcpy(payload
+ tag_size
, eth_src
, ETH_ADDR_LEN
);
78 /* Modify the TCI field of 'packet', whose data must begin with an Ethernet
79 * header. If a VLAN tag is present, its TCI field is replaced by 'tci'. If a
80 * VLAN tag is not present, one is added with the TCI field set to 'tci'.
82 * Also sets 'packet->l2' to point to the new Ethernet header. */
84 eth_set_vlan_tci(struct ofpbuf
*packet
, ovs_be16 tci
)
86 struct eth_header
*eh
= packet
->data
;
87 struct vlan_eth_header
*veh
;
89 if (packet
->size
>= sizeof(struct vlan_eth_header
)
90 && eh
->eth_type
== htons(ETH_TYPE_VLAN
)) {
94 /* Insert new 802.1Q header. */
95 struct vlan_eth_header tmp
;
96 memcpy(tmp
.veth_dst
, eh
->eth_dst
, ETH_ADDR_LEN
);
97 memcpy(tmp
.veth_src
, eh
->eth_src
, ETH_ADDR_LEN
);
98 tmp
.veth_type
= htons(ETH_TYPE_VLAN
);
100 tmp
.veth_next_type
= eh
->eth_type
;
102 veh
= ofpbuf_push_uninit(packet
, VLAN_HEADER_LEN
);
103 memcpy(veh
, &tmp
, sizeof tmp
);
105 packet
->l2
= packet
->data
;
108 /* Stores the string representation of the IPv6 address 'addr' into the
109 * character array 'addr_str', which must be at least INET6_ADDRSTRLEN
112 format_ipv6_addr(char *addr_str
, const struct in6_addr
*addr
)
114 inet_ntop(AF_INET6
, addr
, addr_str
, INET6_ADDRSTRLEN
);
118 print_ipv6_addr(struct ds
*string
, const struct in6_addr
*addr
)
120 char addr_str
[INET6_ADDRSTRLEN
];
122 format_ipv6_addr(addr_str
, addr
);
123 ds_put_format(string
, "%s", addr_str
);
126 struct in6_addr
ipv6_addr_bitand(const struct in6_addr
*a
,
127 const struct in6_addr
*b
)
133 for (i
=0; i
<4; i
++) {
134 dst
.s6_addr32
[i
] = a
->s6_addr32
[i
] & b
->s6_addr32
[i
];
137 for (i
=0; i
<16; i
++) {
138 dst
.s6_addr
[i
] = a
->s6_addr
[i
] & b
->s6_addr
[i
];
145 /* Returns an in6_addr consisting of 'mask' high-order 1-bits and 128-N
146 * low-order 0-bits. */
148 ipv6_create_mask(int mask
)
150 struct in6_addr netmask
;
151 uint8_t *netmaskp
= &netmask
.s6_addr
[0];
153 memset(&netmask
, 0, sizeof netmask
);
161 *netmaskp
= 0xff << (8 - mask
);
167 /* Given the IPv6 netmask 'netmask', returns the number of bits of the
168 * IPv6 address that it wildcards. 'netmask' must be a CIDR netmask (see
169 * ipv6_is_cidr()). */
171 ipv6_count_cidr_bits(const struct in6_addr
*netmask
)
175 const uint8_t *netmaskp
= &netmask
->s6_addr
[0];
177 assert(ipv6_is_cidr(netmask
));
179 for (i
=0; i
<16; i
++) {
180 if (netmaskp
[i
] == 0xff) {
185 for(nm
= netmaskp
[i
]; nm
; nm
<<= 1) {
196 /* Returns true if 'netmask' is a CIDR netmask, that is, if it consists of N
197 * high-order 1-bits and 128-N low-order 0-bits. */
199 ipv6_is_cidr(const struct in6_addr
*netmask
)
201 const uint8_t *netmaskp
= &netmask
->s6_addr
[0];
204 for (i
=0; i
<16; i
++) {
205 if (netmaskp
[i
] != 0xff) {
206 uint8_t x
= ~netmaskp
[i
];
221 /* Populates 'b' with an Ethernet II packet headed with the given 'eth_dst',
222 * 'eth_src' and 'eth_type' parameters. A payload of 'size' bytes is allocated
223 * in 'b' and returned. This payload may be populated with appropriate
224 * information by the caller.
226 * The returned packet has enough headroom to insert an 802.1Q VLAN header if
229 eth_compose(struct ofpbuf
*b
, const uint8_t eth_dst
[ETH_ADDR_LEN
],
230 const uint8_t eth_src
[ETH_ADDR_LEN
], uint16_t eth_type
,
234 struct eth_header
*eth
;
238 ofpbuf_prealloc_tailroom(b
, ETH_HEADER_LEN
+ VLAN_HEADER_LEN
+ size
);
239 ofpbuf_reserve(b
, VLAN_HEADER_LEN
);
240 eth
= ofpbuf_put_uninit(b
, ETH_HEADER_LEN
);
241 data
= ofpbuf_put_uninit(b
, size
);
243 memcpy(eth
->eth_dst
, eth_dst
, ETH_ADDR_LEN
);
244 memcpy(eth
->eth_src
, eth_src
, ETH_ADDR_LEN
);
245 eth
->eth_type
= htons(eth_type
);
250 /* Populates 'b' with an Ethernet LLC+SNAP packet headed with the given
251 * 'eth_dst', 'eth_src', 'snap_org', and 'snap_type'. A payload of 'size'
252 * bytes is allocated in 'b' and returned. This payload may be populated with
253 * appropriate information by the caller.
255 * The returned packet has enough headroom to insert an 802.1Q VLAN header if
258 snap_compose(struct ofpbuf
*b
, const uint8_t eth_dst
[ETH_ADDR_LEN
],
259 const uint8_t eth_src
[ETH_ADDR_LEN
],
260 unsigned int oui
, uint16_t snap_type
, size_t size
)
262 struct eth_header
*eth
;
263 struct llc_snap_header
*llc_snap
;
266 /* Compose basic packet structure. (We need the payload size to stick into
267 * the 802.2 header.) */
269 ofpbuf_prealloc_tailroom(b
, ETH_HEADER_LEN
+ VLAN_HEADER_LEN
270 + LLC_SNAP_HEADER_LEN
+ size
);
271 ofpbuf_reserve(b
, VLAN_HEADER_LEN
);
272 eth
= ofpbuf_put_zeros(b
, ETH_HEADER_LEN
);
273 llc_snap
= ofpbuf_put_zeros(b
, LLC_SNAP_HEADER_LEN
);
274 payload
= ofpbuf_put_uninit(b
, size
);
276 /* Compose 802.2 header. */
277 memcpy(eth
->eth_dst
, eth_dst
, ETH_ADDR_LEN
);
278 memcpy(eth
->eth_src
, eth_src
, ETH_ADDR_LEN
);
279 eth
->eth_type
= htons(b
->size
- ETH_HEADER_LEN
);
281 /* Compose LLC, SNAP headers. */
282 llc_snap
->llc
.llc_dsap
= LLC_DSAP_SNAP
;
283 llc_snap
->llc
.llc_ssap
= LLC_SSAP_SNAP
;
284 llc_snap
->llc
.llc_cntl
= LLC_CNTL_SNAP
;
285 llc_snap
->snap
.snap_org
[0] = oui
>> 16;
286 llc_snap
->snap
.snap_org
[1] = oui
>> 8;
287 llc_snap
->snap
.snap_org
[2] = oui
;
288 llc_snap
->snap
.snap_type
= htons(snap_type
);
293 /* Populates 'pdu' with a LACP PDU comprised of 'actor' and 'partner'. */
295 compose_lacp_pdu(const struct lacp_info
*actor
,
296 const struct lacp_info
*partner
, struct lacp_pdu
*pdu
)
298 memset(pdu
, 0, sizeof *pdu
);
307 pdu
->partner_type
= 2;
308 pdu
->partner_len
= 20;
309 pdu
->partner
= *partner
;
311 pdu
->collector_type
= 3;
312 pdu
->collector_len
= 16;
313 pdu
->collector_delay
= htons(0);
316 /* Parses 'b' which represents a packet containing a LACP PDU. This function
317 * returns NULL if 'b' is malformed, or does not represent a LACP PDU format
318 * supported by OVS. Otherwise, it returns a pointer to the lacp_pdu contained
320 const struct lacp_pdu
*
321 parse_lacp_packet(const struct ofpbuf
*b
)
323 const struct lacp_pdu
*pdu
;
325 pdu
= ofpbuf_at(b
, (uint8_t *)b
->l3
- (uint8_t *)b
->data
, LACP_PDU_LEN
);
327 if (pdu
&& pdu
->subtype
== 1
328 && pdu
->actor_type
== 1 && pdu
->actor_len
== 20
329 && pdu
->partner_type
== 2 && pdu
->partner_len
== 20) {