4 * Copyright (c)2005 YAMAMOTO Takashi,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD$");
32 #include <sys/param.h>
37 #include <net/if_dl.h>
38 #include <net/if_ether.h>
39 #include <net/if_vlanvar.h>
41 #include <net/agr/if_agrethervar.h>
43 #include <netinet/in.h>
44 #include <netinet/in_systm.h>
45 #include <netinet/ip.h>
46 #include <netinet/ip6.h>
48 #define HASH(p, l, h) hash32_buf((p), (l), (h))
50 static const void *agr_m_extract(struct mbuf
*, int, int, void *);
53 agr_m_extract(struct mbuf
*m
, int off
, int len
, void *buf
)
57 KASSERT((m
->m_flags
& M_PKTHDR
) != 0);
59 if (m
->m_pkthdr
.len
< off
+ len
) {
61 } else if (m
->m_len
>= off
+ len
) {
62 result
= mtod(m
, char *) + off
;
64 m_copydata(m
, off
, len
, buf
);
72 agrether_hashmbuf(struct agr_softc
*sc
, struct mbuf
*m
)
74 struct ether_header eh_store
;
75 const struct ether_header
*eh
;
76 uint32_t hash
= HASH32_BUF_INIT
;
82 eh
= agr_m_extract(m
, off
, sizeof(*eh
), &eh_store
);
87 hash
= HASH(&eh
->ether_dhost
, sizeof(eh
->ether_dhost
), hash
);
88 hash
= HASH(&eh
->ether_shost
, sizeof(eh
->ether_shost
), hash
);
89 etype
= eh
->ether_type
;
91 if (etype
== htobe16(ETHERTYPE_VLAN
)) {
92 struct ether_vlan_header vlanhdr_store
;
93 const struct ether_vlan_header
*vlanhdr
;
95 vlanhdr
= agr_m_extract(m
, off
, sizeof(*vlanhdr
),
97 if (vlanhdr
== NULL
) {
101 tci
= vlanhdr
->evl_tag
;
102 etype
= vlanhdr
->evl_proto
;
103 off
+= sizeof(*vlanhdr
) - sizeof(*eh
);
104 } else if ((mtag
= m_tag_find(m
, PACKET_TAG_VLAN
, NULL
)) != NULL
) {
105 tci
= htole16((*(u_int
*)(mtag
+ 1)) & 0xffff);
109 hash
= HASH(&tci
, sizeof(tci
), hash
);
112 if (etype
== htobe16(ETHERTYPE_IP
)) {
116 ip
= agr_m_extract(m
, off
, sizeof(*ip
), &ip_store
);
121 hash
= HASH(&ip
->ip_src
, sizeof(ip
->ip_src
), hash
);
122 hash
= HASH(&ip
->ip_dst
, sizeof(ip
->ip_dst
), hash
);
123 hash
= HASH(&ip
->ip_p
, sizeof(ip
->ip_p
), hash
);
125 /* use port numbers for tcp and udp? */
127 } else if (etype
== htobe16(ETHERTYPE_IPV6
)) {
128 struct ip6_hdr ip6_store
;
129 const struct ip6_hdr
*ip6
;
132 ip6
= agr_m_extract(m
, off
, sizeof(*ip6
), &ip6_store
);
137 hash
= HASH(&ip6
->ip6_src
, sizeof(ip6
->ip6_src
), hash
);
138 hash
= HASH(&ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
), hash
);
139 /* hash = HASH(&ip6->ip6_nxt, sizeof(ip6->ip6_nxt), hash); */
141 flowlabel
= ip6
->ip6_flow
& IPV6_FLOWLABEL_MASK
;
142 hash
= HASH(&flowlabel
, sizeof(flowlabel
), hash
);
144 /* use port numbers for tcp and udp? */