* Re: [PATCH 1/1] vxlan: insert ipv6 macro
2016-10-12 13:16 ` Jiri Benc
@ 2016-10-13 5:28 ` zhuyj
2016-10-13 5:30 ` zhuyj
0 siblings, 1 reply; 6+ messages in thread
From: zhuyj @ 2016-10-13 5:28 UTC (permalink / raw)
To: Jiri Benc
Cc: netdev, pabeni, daniel, Pravin B Shelar, Alexander Duyck, hannes,
David S. Miller
[-- Attachment #1: Type: text/plain, Size: 939 bytes --]
Hi, Jiri
The dumped source code is in the attachment. Please check it. I think
this file can explain all.
If anything, please just let me know.
Thanks a lot.
On Wed, Oct 12, 2016 at 9:16 PM, Jiri Benc <jbenc@redhat.com> wrote:
> On Wed, 12 Oct 2016 21:01:54 +0800, zhuyj wrote:
>> How to explain the following source code? As you mentioned, are the
>> #ifdefs in the following source pointless?
>
> They are not, the code would not compile without them. Look how struct
> vxlan_dev is defined.
>
> Those are really basic questions you have. I suggest you try yourself
> before asking such questions next time. In this case, you could
> trivially remove the #ifdef and see for yourself, as I explained in the
> previous email. Please do not try to offload your homework to other
> people. It's very obvious you didn't even try to understand this, even
> after the feedback you received.
>
> And do not top post.
>
> Thanks,
>
> Jiri
[-- Attachment #2: dump-vxlan.txt --]
[-- Type: text/plain, Size: 602468 bytes --]
vxlan.ko: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <__vxlan_find_mac>:
}
/* Look up Ethernet address in forwarding table */
static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
0: e8 00 00 00 00 callq 5 <__vxlan_find_mac+0x5>
5: 55 push %rbp
6: 48 8b 16 mov (%rsi),%rdx
9: 48 b8 eb 83 b5 80 46 movabs $0x61c8864680b583eb,%rax
10: 86 c8 61
13: 48 89 e5 mov %rsp,%rbp
16: 48 c1 e2 10 shl $0x10,%rdx
1a: 48 0f af c2 imul %rdx,%rax
1e: 48 c1 e8 38 shr $0x38,%rax
22: 48 8d 84 c7 60 01 00 lea 0x160(%rdi,%rax,8),%rax
29: 00
2a: 48 8b 00 mov (%rax),%rax
2d: 48 85 c0 test %rax,%rax
30: 74 22 je 54 <__vxlan_find_mac+0x54>
32: 8b 3e mov (%rsi),%edi
34: 0f b7 76 04 movzwl 0x4(%rsi),%esi
struct hlist_head *head = vxlan_fdb_head(vxlan, mac);
struct vxlan_fdb *f;
hlist_for_each_entry_rcu(f, head, hlist) {
38: 89 f2 mov %esi,%edx
3a: 66 33 50 44 xor 0x44(%rax),%dx
3e: 8b 48 40 mov 0x40(%rax),%ecx
41: 31 f9 xor %edi,%ecx
}
/* Look up Ethernet address in forwarding table */
static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
43: 0f b7 d2 movzwl %dx,%edx
struct hlist_head *head = vxlan_fdb_head(vxlan, mac);
struct vxlan_fdb *f;
hlist_for_each_entry_rcu(f, head, hlist) {
46: 09 d1 or %edx,%ecx
48: 74 08 je 52 <__vxlan_find_mac+0x52>
4a: 48 8b 00 mov (%rax),%rax
4d: 48 85 c0 test %rax,%rax
50: 75 e6 jne 38 <__vxlan_find_mac+0x38>
52: 5d pop %rbp
53: c3 retq
54: 31 c0 xor %eax,%eax
56: 5d pop %rbp
57: c3 retq
58: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
5f: 00
0000000000000060 <vxlan_set_multicast_list>:
60: e8 00 00 00 00 callq 65 <vxlan_set_multicast_list+0x5>
65: 55 push %rbp
66: 48 89 e5 mov %rsp,%rbp
if (ether_addr_equal(mac, f->eth_addr))
69: 5d pop %rbp
6a: c3 retq
6b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000000070 <vxlan_get_size>:
70: e8 00 00 00 00 callq 75 <vxlan_get_size+0x5>
75: 55 push %rbp
76: b8 c8 00 00 00 mov $0xc8,%eax
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
7b: 48 89 e5 mov %rsp,%rbp
const u8 *mac)
{
struct hlist_head *head = vxlan_fdb_head(vxlan, mac);
struct vxlan_fdb *f;
hlist_for_each_entry_rcu(f, head, hlist) {
7e: 5d pop %rbp
7f: c3 retq
0000000000000080 <vxlan_get_link_net>:
80: e8 00 00 00 00 callq 85 <vxlan_get_link_net+0x5>
if (ether_addr_equal(mac, f->eth_addr))
return f;
}
return NULL;
85: 55 push %rbp
}
86: 48 8b 87 78 08 00 00 mov 0x878(%rdi),%rax
8d: 48 89 e5 mov %rsp,%rbp
return ret;
}
/* Stub, nothing needs to be done. */
static void vxlan_set_multicast_list(struct net_device *dev)
{
90: 5d pop %rbp
91: c3 retq
92: 0f 1f 40 00 nopl 0x0(%rax)
96: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
9d: 00 00 00
00000000000000a0 <vxlan_init_net>:
list_del(&vxlan->next);
unregister_netdevice_queue(dev, head);
}
static size_t vxlan_get_size(const struct net_device *dev)
{
a0: e8 00 00 00 00 callq a5 <vxlan_init_net+0x5>
a5: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # ab <vxlan_init_net+0xb>
ab: 48 8b 97 88 14 00 00 mov 0x1488(%rdi),%rdx
nla_put_failure:
return -EMSGSIZE;
}
static struct net *vxlan_get_link_net(const struct net_device *dev)
{
b2: 55 push %rbp
b3: 83 e8 01 sub $0x1,%eax
struct vxlan_dev *vxlan = netdev_priv(dev);
return vxlan->net;
b6: 48 89 e5 mov %rsp,%rbp
b9: 48 98 cltq
bb: 48 8b 54 c2 18 mov 0x18(%rdx,%rax,8),%rdx
}
c0: 48 89 12 mov %rdx,(%rdx)
c3: 48 89 52 08 mov %rdx,0x8(%rdx)
c7: 48 8d 42 10 lea 0x10(%rdx),%rax
cb: c7 82 10 08 00 00 00 movl $0x0,0x810(%rdx)
d2: 00 00 00
struct net_generic *ng;
void *ptr;
rcu_read_lock();
ng = rcu_dereference(net->gen);
ptr = ng->ptr[id - 1];
d5: 48 81 c2 10 08 00 00 add $0x810,%rdx
dc: 48 c7 00 00 00 00 00 movq $0x0,(%rax)
e3: 48 83 c0 08 add $0x8,%rax
static struct notifier_block vxlan_notifier_block __read_mostly = {
.notifier_call = vxlan_netdevice_event,
};
static __net_init int vxlan_init_net(struct net *net)
{
e7: 48 39 d0 cmp %rdx,%rax
ea: 75 f0 jne dc <vxlan_init_net+0x3c>
ec: 31 c0 xor %eax,%eax
ee: 5d pop %rbp
ef: c3 retq
00000000000000f0 <vxlan_find_sock>:
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
f0: e8 00 00 00 00 callq f5 <vxlan_find_sock+0x5>
struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
WRITE_ONCE(list->next, list);
list->prev = list;
f5: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # fb <vxlan_find_sock+0xb>
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
unsigned int h;
INIT_LIST_HEAD(&vn->vxlan_list);
spin_lock_init(&vn->sock_lock);
fb: 55 push %rbp
fc: 41 89 d0 mov %edx,%r8d
ff: 4c 8b 8f 88 14 00 00 mov 0x1488(%rdi),%r9
106: 66 c1 c2 08 rol $0x8,%dx
10a: 81 e1 00 7d 00 00 and $0x7d00,%ecx
for (h = 0; h < PORT_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vn->sock_list[h]);
110: 48 89 e5 mov %rsp,%rbp
113: 8d 78 ff lea -0x1(%rax),%edi
116: 0f b7 c2 movzwl %dx,%eax
unsigned int h;
INIT_LIST_HEAD(&vn->vxlan_list);
spin_lock_init(&vn->sock_lock);
for (h = 0; h < PORT_HASH_SIZE; ++h)
119: 69 c0 47 86 c8 61 imul $0x61c88647,%eax,%eax
INIT_HLIST_HEAD(&vn->sock_list[h]);
return 0;
}
11f: 48 63 ff movslq %edi,%rdi
/* Find VXLAN socket based on network namespace, address family and UDP port
* and enabled unshareable flags.
*/
static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
__be16 port, u32 flags)
{
122: 49 8b 54 f9 18 mov 0x18(%r9,%rdi,8),%rdx
127: c1 e8 18 shr $0x18,%eax
12a: 48 8d 44 c2 10 lea 0x10(%rdx,%rax,8),%rax
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
12f: 48 8b 00 mov (%rax),%rax
132: 48 85 c0 test %rax,%rax
135: 75 1a jne 151 <vxlan_find_sock+0x61>
/* Socket hash table head */
static inline struct hlist_head *vs_head(struct net *net, __be16 port)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
137: 31 c0 xor %eax,%eax
139: 5d pop %rbp
static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
__be16 port, u32 flags)
{
struct vxlan_sock *vs;
flags &= VXLAN_F_RCV_FLAGS;
13a: c3 retq
13b: 66 3b 72 10 cmp 0x10(%rdx),%si
13f: 75 08 jne 149 <vxlan_find_sock+0x59>
/* Find VXLAN socket based on network namespace, address family and UDP port
* and enabled unshareable flags.
*/
static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
__be16 port, u32 flags)
{
141: 3b 88 1c 20 00 00 cmp 0x201c(%rax),%ecx
struct vxlan_sock *vs;
flags &= VXLAN_F_RCV_FLAGS;
hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
147: 74 f0 je 139 <vxlan_find_sock+0x49>
149: 48 8b 00 mov (%rax),%rax
14c: 48 85 c0 test %rax,%rax
14f: 74 e8 je 139 <vxlan_find_sock+0x49>
151: 48 8b 50 10 mov 0x10(%rax),%rdx
155: 48 8b 52 20 mov 0x20(%rdx),%rdx
159: 66 44 3b 82 e0 02 00 cmp 0x2e0(%rdx),%r8w
160: 00
161: 75 e6 jne 149 <vxlan_find_sock+0x59>
163: eb d6 jmp 13b <vxlan_find_sock+0x4b>
165: 90 nop
166: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
16d: 00 00 00
0000000000000170 <vxlan_find_vni>:
if (inet_sk(vs->sock->sk)->inet_sport == port &&
170: e8 00 00 00 00 callq 175 <vxlan_find_vni+0x5>
vxlan_get_sk_family(vs) == family &&
175: 55 push %rbp
176: 48 89 e5 mov %rsp,%rbp
179: 53 push %rbx
17a: 89 f3 mov %esi,%ebx
{
struct vxlan_sock *vs;
flags &= VXLAN_F_RCV_FLAGS;
hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
17c: 89 d6 mov %edx,%esi
17e: 0f b7 d1 movzwl %cx,%edx
if (inet_sk(vs->sock->sk)->inet_sport == port &&
181: 44 89 c1 mov %r8d,%ecx
184: 0f b7 f6 movzwl %si,%esi
187: e8 64 ff ff ff callq f0 <vxlan_find_sock>
18c: 48 85 c0 test %rax,%rax
18f: 74 2f je 1c0 <vxlan_find_vni+0x50>
191: f6 80 1d 20 00 00 20 testb $0x20,0x201d(%rax)
198: 75 2b jne 1c5 <vxlan_find_vni+0x55>
19a: 69 d3 47 86 c8 61 imul $0x61c88647,%ebx,%edx
/* Look up VNI in a per net namespace table */
static struct vxlan_dev *vxlan_find_vni(struct net *net, __be32 vni,
sa_family_t family, __be16 port,
u32 flags)
{
1a0: c1 ea 16 shr $0x16,%edx
1a3: 48 8d 44 d0 10 lea 0x10(%rax,%rdx,8),%rax
1a8: 48 8b 50 08 mov 0x8(%rax),%rdx
1ac: 31 c0 xor %eax,%eax
struct vxlan_sock *vs;
vs = vxlan_find_sock(net, family, port, flags);
1ae: 48 85 d2 test %rdx,%rdx
1b1: 74 0f je 1c2 <vxlan_find_vni+0x52>
1b3: 3b 5a 60 cmp 0x60(%rdx),%ebx
1b6: 74 13 je 1cb <vxlan_find_vni+0x5b>
1b8: 48 8b 12 mov (%rdx),%rdx
1bb: 48 85 d2 test %rdx,%rdx
if (!vs)
1be: 75 f3 jne 1b3 <vxlan_find_vni+0x43>
1c0: 31 c0 xor %eax,%eax
static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
{
struct vxlan_dev *vxlan;
/* For flow based devices, map all packets to VNI 0 */
if (vs->flags & VXLAN_F_COLLECT_METADATA)
1c2: 5b pop %rbx
1c3: 5d pop %rbp
1c4: c3 retq
1c5: 31 d2 xor %edx,%edx
1c7: 31 db xor %ebx,%ebx
1c9: eb d8 jmp 1a3 <vxlan_find_vni+0x33>
1cb: 48 89 d0 mov %rdx,%rax
1ce: 5b pop %rbx
1cf: 5d pop %rbp
1d0: c3 retq
1d1: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
vni = 0;
hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
1d6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
1dd: 00 00 00
00000000000001e0 <vxlan_validate>:
1e0: e8 00 00 00 00 callq 1e5 <vxlan_validate+0x5>
if (vxlan->default_dst.remote_vni == vni)
1e5: 55 push %rbp
1e6: 48 8b 47 08 mov 0x8(%rdi),%rax
1ea: 48 89 e5 mov %rsp,%rbp
/* For flow based devices, map all packets to VNI 0 */
if (vs->flags & VXLAN_F_COLLECT_METADATA)
vni = 0;
hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
1ed: 48 85 c0 test %rax,%rax
{
struct vxlan_sock *vs;
vs = vxlan_find_sock(net, family, port, flags);
if (!vs)
return NULL;
1f0: 74 3c je 22e <vxlan_validate+0x4e>
return vxlan_vs_find_vni(vs, vni);
}
1f2: 66 83 38 0a cmpw $0xa,(%rax)
static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
{
struct vxlan_dev *vxlan;
/* For flow based devices, map all packets to VNI 0 */
if (vs->flags & VXLAN_F_COLLECT_METADATA)
1f6: 74 26 je 21e <vxlan_validate+0x3e>
vni = 0;
1f8: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
if (vxlan->default_dst.remote_vni == vni)
1fd: b8 ea ff ff ff mov $0xffffffea,%eax
vs = vxlan_find_sock(net, family, port, flags);
if (!vs)
return NULL;
return vxlan_vs_find_vni(vs, vni);
}
202: 5d pop %rbp
203: c3 retq
204: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
20b: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
[IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
};
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
{
212: e8 00 00 00 00 callq 217 <vxlan_validate+0x37>
if (tb[IFLA_ADDRESS]) {
217: b8 ea ff ff ff mov $0xffffffea,%eax
[IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
};
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
{
21c: 5d pop %rbp
if (tb[IFLA_ADDRESS]) {
21d: c3 retq
21e: 8b 50 04 mov 0x4(%rax),%edx
221: f6 c2 01 test $0x1,%dl
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
224: 75 46 jne 26c <vxlan_validate+0x8c>
226: 0f b7 40 08 movzwl 0x8(%rax),%eax
22a: 09 d0 or %edx,%eax
22c: 74 3e je 26c <vxlan_validate+0x8c>
= nla_data(data[IFLA_VXLAN_PORT_RANGE]);
if (ntohs(p->high) < ntohs(p->low)) {
pr_debug("port range %u .. %u not valid\n",
ntohs(p->low), ntohs(p->high));
return -EINVAL;
22e: 48 85 f6 test %rsi,%rsi
231: 74 5e je 291 <vxlan_validate+0xb1>
}
}
return 0;
}
233: 48 8b 46 08 mov 0x8(%rsi),%rax
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
{
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
pr_debug("invalid link address (not ethernet)\n");
237: 48 85 c0 test %rax,%rax
23a: 74 09 je 245 <vxlan_validate+0x65>
23c: 81 78 04 fe ff ff 00 cmpl $0xfffffe,0x4(%rax)
243: 77 71 ja 2b6 <vxlan_validate+0xd6>
245: 48 8b 46 50 mov 0x50(%rsi),%rax
return -EINVAL;
249: 48 85 c0 test %rax,%rax
return -EINVAL;
}
}
return 0;
}
24c: 74 64 je 2b2 <vxlan_validate+0xd2>
* By definition the broadcast address is also a multicast address.
*/
static inline bool is_multicast_ether_addr(const u8 *addr)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
u32 a = *(const u32 *)addr;
24e: 0f b7 48 06 movzwl 0x6(%rax),%ecx
*/
static inline bool is_valid_ether_addr(const u8 *addr)
{
/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
* explicitly check for it here. */
return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
252: 0f b7 50 04 movzwl 0x4(%rax),%edx
256: 31 c0 xor %eax,%eax
258: 66 c1 c1 08 rol $0x8,%cx
25c: 66 c1 c2 08 rol $0x8,%dx
pr_debug("invalid all zero ethernet address\n");
return -EADDRNOTAVAIL;
}
}
if (!data)
260: 66 39 d1 cmp %dx,%cx
return -EINVAL;
if (data[IFLA_VXLAN_ID]) {
263: 73 9d jae 202 <vxlan_validate+0x22>
265: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
26a: eb 91 jmp 1fd <vxlan_validate+0x1d>
__u32 id = nla_get_u32(data[IFLA_VXLAN_ID]);
if (id >= VXLAN_VID_MASK)
26c: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
271: b8 9d ff ff ff mov $0xffffff9d,%eax
return -ERANGE;
}
if (data[IFLA_VXLAN_PORT_RANGE]) {
276: 5d pop %rbp
277: c3 retq
278: 0f b7 c9 movzwl %cx,%ecx
27b: 0f b7 d2 movzwl %dx,%edx
const struct ifla_vxlan_port_range *p
= nla_data(data[IFLA_VXLAN_PORT_RANGE]);
if (ntohs(p->high) < ntohs(p->low)) {
27e: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
285: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
28c: e8 00 00 00 00 callq 291 <vxlan_validate+0xb1>
291: b8 ea ff ff ff mov $0xffffffea,%eax
296: 5d pop %rbp
297: c3 retq
298: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
#include <linux/stringify.h>
#include <linux/types.h>
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
{
asm_volatile_goto("1:"
29f: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
return -EINVAL;
}
}
return 0;
}
2a6: e8 00 00 00 00 callq 2ab <vxlan_validate+0xcb>
if (data[IFLA_VXLAN_PORT_RANGE]) {
const struct ifla_vxlan_port_range *p
= nla_data(data[IFLA_VXLAN_PORT_RANGE]);
if (ntohs(p->high) < ntohs(p->low)) {
pr_debug("port range %u .. %u not valid\n",
2ab: b8 9d ff ff ff mov $0xffffff9d,%eax
2b0: 5d pop %rbp
2b1: c3 retq
2b2: 31 c0 xor %eax,%eax
2b4: 5d pop %rbp
2b5: c3 retq
2b6: b8 de ff ff ff mov $0xffffffde,%eax
2bb: 5d pop %rbp
2bc: c3 retq
2bd: 0f 1f 00 nopl (%rax)
00000000000002c0 <vxlan_fdb_free>:
2c0: e8 00 00 00 00 callq 2c5 <vxlan_fdb_free+0x5>
ntohs(p->low), ntohs(p->high));
return -EINVAL;
2c5: 55 push %rbp
}
}
return 0;
}
2c6: 48 89 e5 mov %rsp,%rbp
pr_debug("invalid link address (not ethernet)\n");
return -EINVAL;
}
if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
pr_debug("invalid all zero ethernet address\n");
2c9: 41 56 push %r14
2cb: 41 55 push %r13
2cd: 41 54 push %r12
2cf: 53 push %rbx
2d0: 4c 8d 6f 20 lea 0x20(%rdi),%r13
2d4: 48 8b 47 20 mov 0x20(%rdi),%rax
2d8: 4c 8d 77 f0 lea -0x10(%rdi),%r14
return -EADDRNOTAVAIL;
2dc: 48 8b 08 mov (%rax),%rcx
2df: 49 39 c5 cmp %rax,%r13
ntohs(p->low), ntohs(p->high));
return -EINVAL;
}
}
return 0;
2e2: 4c 8d 60 d8 lea -0x28(%rax),%r12
return -EINVAL;
if (data[IFLA_VXLAN_ID]) {
__u32 id = nla_get_u32(data[IFLA_VXLAN_ID]);
if (id >= VXLAN_VID_MASK)
return -ERANGE;
2e6: 48 8d 59 d8 lea -0x28(%rcx),%rbx
2ea: 74 26 je 312 <vxlan_fdb_free+0x52>
return -EINVAL;
}
}
return 0;
}
2ec: 49 8d 7c 24 48 lea 0x48(%r12),%rdi
return 0;
}
static void vxlan_fdb_free(struct rcu_head *head)
{
2f1: e8 00 00 00 00 callq 2f6 <vxlan_fdb_free+0x36>
2f6: 4c 89 e7 mov %r12,%rdi
2f9: 49 89 dc mov %rbx,%r12
2fc: e8 00 00 00 00 callq 301 <vxlan_fdb_free+0x41>
struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
struct vxlan_rdst *rd, *nd;
list_for_each_entry_safe(rd, nd, &f->remotes, list) {
301: 48 8d 43 28 lea 0x28(%rbx),%rax
305: 48 8b 53 28 mov 0x28(%rbx),%rdx
return 0;
}
static void vxlan_fdb_free(struct rcu_head *head)
{
struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
309: 4c 39 e8 cmp %r13,%rax
struct vxlan_rdst *rd, *nd;
list_for_each_entry_safe(rd, nd, &f->remotes, list) {
30c: 48 8d 5a d8 lea -0x28(%rdx),%rbx
310: 75 da jne 2ec <vxlan_fdb_free+0x2c>
312: 4c 89 f7 mov %r14,%rdi
315: e8 00 00 00 00 callq 31a <vxlan_fdb_free+0x5a>
31a: 5b pop %rbx
31b: 41 5c pop %r12
dst_cache_destroy(&rd->dst_cache);
31d: 41 5d pop %r13
31f: 41 5e pop %r14
321: 5d pop %rbp
322: c3 retq
323: 0f 1f 00 nopl (%rax)
kfree(rd);
326: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
32d: 00 00 00
0000000000000330 <gro_cell_poll>:
330: 55 push %rbp
static void vxlan_fdb_free(struct rcu_head *head)
{
struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
struct vxlan_rdst *rd, *nd;
list_for_each_entry_safe(rd, nd, &f->remotes, list) {
331: 48 89 e5 mov %rsp,%rbp
334: 41 56 push %r14
336: 41 55 push %r13
338: 45 31 ed xor %r13d,%r13d
33b: 85 f6 test %esi,%esi
33d: 41 54 push %r12
33f: 53 push %rbx
340: 7e 6e jle 3b0 <gro_cell_poll+0x80>
dst_cache_destroy(&rd->dst_cache);
kfree(rd);
}
kfree(f);
342: 41 89 f5 mov %esi,%r13d
345: 48 8b 77 e8 mov -0x18(%rdi),%rsi
349: 4c 8d 77 e8 lea -0x18(%rdi),%r14
}
34d: 48 89 fb mov %rdi,%rbx
350: 49 39 f6 cmp %rsi,%r14
353: 74 4d je 3a2 <gro_cell_poll+0x72>
355: 48 85 f6 test %rsi,%rsi
358: 74 48 je 3a2 <gro_cell_poll+0x72>
35a: 45 31 e4 xor %r12d,%r12d
35d: 83 6b f8 01 subl $0x1,-0x8(%rbx)
return NET_RX_SUCCESS;
}
/* called under BH context */
static inline int gro_cell_poll(struct napi_struct *napi, int budget)
{
361: 48 89 df mov %rbx,%rdi
364: 41 83 c4 01 add $0x1,%r12d
struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
struct sk_buff *skb;
int work_done = 0;
368: 48 8b 16 mov (%rsi),%rdx
while (work_done < budget) {
36b: 48 8b 46 08 mov 0x8(%rsi),%rax
return NET_RX_SUCCESS;
}
/* called under BH context */
static inline int gro_cell_poll(struct napi_struct *napi, int budget)
{
36f: 48 c7 06 00 00 00 00 movq $0x0,(%rsi)
* The reference count is not incremented and the reference is therefore
* volatile. Use with caution.
*/
static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
{
struct sk_buff *skb = list_->next;
376: 48 c7 46 08 00 00 00 movq $0x0,0x8(%rsi)
37d: 00
struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
struct sk_buff *skb;
int work_done = 0;
while (work_done < budget) {
skb = __skb_dequeue(&cell->napi_skbs);
37e: 48 89 42 08 mov %rax,0x8(%rdx)
*/
struct sk_buff *skb_dequeue(struct sk_buff_head *list);
static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
{
struct sk_buff *skb = skb_peek(list);
if (skb)
382: 48 89 10 mov %rdx,(%rax)
385: e8 00 00 00 00 callq 38a <gro_cell_poll+0x5a>
38a: 45 39 e5 cmp %r12d,%r13d
void skb_unlink(struct sk_buff *skb, struct sk_buff_head *list);
static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
{
struct sk_buff *next, *prev;
list->qlen--;
38d: 74 21 je 3b0 <gro_cell_poll+0x80>
38f: 48 8b 73 e8 mov -0x18(%rbx),%rsi
if (!skb)
break;
napi_gro_receive(napi, skb);
393: 48 85 f6 test %rsi,%rsi
work_done++;
396: 74 05 je 39d <gro_cell_poll+0x6d>
next = skb->next;
398: 4c 39 f6 cmp %r14,%rsi
prev = skb->prev;
39b: 75 c0 jne 35d <gro_cell_poll+0x2d>
39d: 45 89 e5 mov %r12d,%r13d
skb->next = skb->prev = NULL;
3a0: eb 03 jmp 3a5 <gro_cell_poll+0x75>
3a2: 45 31 ed xor %r13d,%r13d
3a5: 44 89 ee mov %r13d,%esi
3a8: 48 89 df mov %rbx,%rdi
3ab: e8 00 00 00 00 callq 3b0 <gro_cell_poll+0x80>
next->prev = prev;
3b0: 5b pop %rbx
3b1: 44 89 e8 mov %r13d,%eax
prev->next = next;
3b4: 41 5c pop %r12
while (work_done < budget) {
skb = __skb_dequeue(&cell->napi_skbs);
if (!skb)
break;
napi_gro_receive(napi, skb);
3b6: 41 5d pop %r13
3b8: 41 5e pop %r14
{
struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
struct sk_buff *skb;
int work_done = 0;
while (work_done < budget) {
3ba: 5d pop %rbp
3bb: c3 retq
3bc: 0f 1f 40 00 nopl 0x0(%rax)
00000000000003c0 <vxlan_setup>:
* The reference count is not incremented and the reference is therefore
* volatile. Use with caution.
*/
static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
{
struct sk_buff *skb = list_->next;
3c0: e8 00 00 00 00 callq 3c5 <vxlan_setup+0x5>
*/
struct sk_buff *skb_dequeue(struct sk_buff_head *list);
static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
{
struct sk_buff *skb = skb_peek(list);
if (skb)
3c5: 55 push %rbp
3c6: be 06 00 00 00 mov $0x6,%esi
3cb: 48 89 e5 mov %rsp,%rbp
skb = __skb_dequeue(&cell->napi_skbs);
if (!skb)
break;
napi_gro_receive(napi, skb);
work_done++;
3ce: 41 55 push %r13
3d0: 41 54 push %r12
/* called under BH context */
static inline int gro_cell_poll(struct napi_struct *napi, int budget)
{
struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
struct sk_buff *skb;
int work_done = 0;
3d2: 53 push %rbx
3d3: 48 8b 9f 38 03 00 00 mov 0x338(%rdi),%rbx
napi_gro_receive(napi, skb);
work_done++;
}
if (work_done < budget)
napi_complete_done(napi, work_done);
3da: 49 89 fc mov %rdi,%r12
3dd: c6 87 74 02 00 00 01 movb $0x1,0x274(%rdi)
return work_done;
}
3e4: 48 89 df mov %rbx,%rdi
3e7: e8 00 00 00 00 callq 3ec <vxlan_setup+0x2c>
3ec: 0f b6 03 movzbl (%rbx),%eax
3ef: 4c 89 e7 mov %r12,%rdi
spin_unlock(&vn->sock_lock);
}
/* Initialize the device structure. */
static void vxlan_setup(struct net_device *dev)
{
3f2: 83 e0 fe and $0xfffffffe,%eax
3f5: 83 c8 02 or $0x2,%eax
* Generate a random Ethernet address (MAC) that is not multicast
* and has the local assigned bit set.
*/
static inline void eth_random_addr(u8 *addr)
{
get_random_bytes(addr, ETH_ALEN);
3f8: 88 03 mov %al,(%rbx)
3fa: 49 8d 9c 24 40 08 00 lea 0x840(%r12),%rbx
401: 00
402: e8 00 00 00 00 callq 407 <vxlan_setup+0x47>
407: 49 8b 8c 24 f0 00 00 mov 0xf0(%r12),%rcx
40e: 00
* and set addr_assign_type so the state can be read by sysfs and be
* used by userspace.
*/
static inline void eth_hw_addr_random(struct net_device *dev)
{
dev->addr_assign_type = NET_ADDR_RANDOM;
40f: 48 b8 89 10 3b 80 20 movabs $0x420803b1089,%rax
416: 04 00 00
* Generate a random Ethernet address (MAC) that is not multicast
* and has the local assigned bit set.
*/
static inline void eth_random_addr(u8 *addr)
{
get_random_bytes(addr, ETH_ALEN);
419: 48 ba 09 10 3b 80 20 movabs $0x20803b1009,%rdx
420: 00 00 00
addr[0] &= 0xfe; /* clear multicast bit */
addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
423: 49 8d bc 24 e0 08 00 lea 0x8e0(%r12),%rdi
42a: 00
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
netif_keep_dst(dev);
dev->priv_flags |= IFF_NO_QUEUE;
INIT_LIST_HEAD(&vxlan->next);
42b: be 00 00 08 00 mov $0x80000,%esi
430: 49 c7 84 24 70 04 00 movq $0x0,0x470(%r12)
437: 00 00 00 00 00
ether_setup(dev);
dev->destructor = free_netdev;
SET_NETDEV_DEVTYPE(dev, &vxlan_type);
dev->features |= NETIF_F_LLTX;
43c: 49 c7 84 24 f8 04 00 movq $0x0,0x4f8(%r12)
443: 00 00 00 00 00
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
dev->vlan_features = dev->features;
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
448: 41 c7 84 24 28 09 00 movl $0x0,0x928(%r12)
44f: 00 00 00 00 00
dev->priv_flags |= IFF_NO_QUEUE;
INIT_LIST_HEAD(&vxlan->next);
spin_lock_init(&vxlan->hash_lock);
init_timer_deferrable(&vxlan->age_timer);
454: 48 09 c8 or %rcx,%rax
457: 48 09 ca or %rcx,%rdx
45a: 31 c9 xor %ecx,%ecx
45c: 49 89 84 24 f0 00 00 mov %rax,0xf0(%r12)
463: 00
unsigned int h;
eth_hw_addr_random(dev);
ether_setup(dev);
dev->destructor = free_netdev;
464: 48 b8 89 00 3b 80 20 movabs $0x420803b0089,%rax
46b: 04 00 00
SET_NETDEV_DEVTYPE(dev, &vxlan_type);
46e: 49 09 84 24 f8 00 00 or %rax,0xf8(%r12)
475: 00
476: 41 8b 84 24 3c 02 00 mov 0x23c(%r12),%eax
47d: 00
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
netif_keep_dst(dev);
dev->priv_flags |= IFF_NO_QUEUE;
INIT_LIST_HEAD(&vxlan->next);
spin_lock_init(&vxlan->hash_lock);
47e: 49 89 94 24 08 01 00 mov %rdx,0x108(%r12)
485: 00
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
dev->vlan_features = dev->features;
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
486: 31 d2 xor %edx,%edx
dev->features |= NETIF_F_LLTX;
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
dev->vlan_features = dev->features;
488: 25 df ff fd ff and $0xfffdffdf,%eax
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
48d: 0d 00 00 20 00 or $0x200000,%eax
492: 41 89 84 24 3c 02 00 mov %eax,0x23c(%r12)
499: 00
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
49a: 49 8d 84 24 50 08 00 lea 0x850(%r12),%rax
4a1: 00
4a2: 49 89 84 24 50 08 00 mov %rax,0x850(%r12)
4a9: 00
netif_keep_dst(dev);
dev->priv_flags |= IFF_NO_QUEUE;
4aa: 49 89 84 24 58 08 00 mov %rax,0x858(%r12)
4b1: 00
dev->features |= NETIF_F_LLTX;
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
dev->vlan_features = dev->features;
4b2: e8 00 00 00 00 callq 4b7 <vxlan_setup+0xf7>
dev->priv_flags |= IFF_NO_QUEUE;
INIT_LIST_HEAD(&vxlan->next);
spin_lock_init(&vxlan->hash_lock);
init_timer_deferrable(&vxlan->age_timer);
4b7: 0f b7 05 00 00 00 00 movzwl 0x0(%rip),%eax # 4be <vxlan_setup+0xfe>
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
netif_keep_dst(dev);
dev->priv_flags |= IFF_NO_QUEUE;
4be: 49 c7 84 24 f8 08 00 movq $0x0,0x8f8(%r12)
4c5: 00 00 00 00 00
INIT_LIST_HEAD(&vxlan->next);
4ca: be 08 00 00 00 mov $0x8,%esi
4cf: 49 89 9c 24 00 09 00 mov %rbx,0x900(%r12)
4d6: 00
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
4d7: 4d 89 a4 24 70 08 00 mov %r12,0x870(%r12)
4de: 00
4df: bf e0 00 00 00 mov $0xe0,%edi
spin_lock_init(&vxlan->hash_lock);
init_timer_deferrable(&vxlan->age_timer);
4e4: 66 c1 c0 08 rol $0x8,%ax
vxlan->age_timer.function = vxlan_cleanup;
vxlan->age_timer.data = (unsigned long) vxlan;
vxlan->cfg.dst_port = htons(vxlan_port);
4e8: 66 41 89 84 24 7c 09 mov %ax,0x97c(%r12)
4ef: 00 00
INIT_LIST_HEAD(&vxlan->next);
spin_lock_init(&vxlan->hash_lock);
init_timer_deferrable(&vxlan->age_timer);
vxlan->age_timer.function = vxlan_cleanup;
4f1: e8 00 00 00 00 callq 4f6 <vxlan_setup+0x136>
4f6: 48 85 c0 test %rax,%rax
4f9: 49 89 84 24 30 09 00 mov %rax,0x930(%r12)
500: 00
vxlan->age_timer.data = (unsigned long) vxlan;
501: 74 77 je 57a <vxlan_setup+0x1ba>
503: 41 bd ff ff ff ff mov $0xffffffff,%r13d
vxlan->cfg.dst_port = htons(vxlan_port);
vxlan->dev = dev;
509: eb 0a jmp 515 <vxlan_setup+0x155>
50b: f0 80 63 28 fe lock andb $0xfe,0x28(%rbx)
static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *dev)
{
int i;
gcells->cells = alloc_percpu(struct gro_cell);
510: f0 80 63 28 fb lock andb $0xfb,0x28(%rbx)
init_timer_deferrable(&vxlan->age_timer);
vxlan->age_timer.function = vxlan_cleanup;
vxlan->age_timer.data = (unsigned long) vxlan;
vxlan->cfg.dst_port = htons(vxlan_port);
515: 41 8d 55 01 lea 0x1(%r13),%edx
519: be 00 01 00 00 mov $0x100,%esi
51e: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
525: 48 63 d2 movslq %edx,%rdx
if (!gcells->cells)
528: e8 00 00 00 00 callq 52d <vxlan_setup+0x16d>
static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *dev)
{
int i;
gcells->cells = alloc_percpu(struct gro_cell);
52d: 3b 05 00 00 00 00 cmp 0x0(%rip),%eax # 533 <vxlan_setup+0x173>
if (!gcells->cells)
533: 41 89 c5 mov %eax,%r13d
536: 7d 42 jge 57a <vxlan_setup+0x1ba>
538: 48 98 cltq
53a: 49 8b 9c 24 30 09 00 mov 0x930(%r12),%rbx
541: 00
*/
static __always_inline void
clear_bit(long nr, volatile unsigned long *addr)
{
if (IS_IMMEDIATE(nr)) {
asm volatile(LOCK_PREFIX "andb %1,%0"
542: b9 40 00 00 00 mov $0x40,%ecx
static inline unsigned int cpumask_next(int n, const struct cpumask *srcp)
{
/* -1 is a legal arg here. */
if (n != -1)
cpumask_check(n);
return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1);
547: 48 03 1c c5 00 00 00 add 0x0(,%rax,8),%rbx
54e: 00
54f: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
556: 4c 89 e7 mov %r12,%rdi
559: 48 8d 73 18 lea 0x18(%rbx),%rsi
return -ENOMEM;
for_each_possible_cpu(i) {
55d: 48 89 1b mov %rbx,(%rbx)
560: 48 89 5b 08 mov %rbx,0x8(%rbx)
564: c7 43 10 00 00 00 00 movl $0x0,0x10(%rbx)
struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
56b: e8 00 00 00 00 callq 570 <vxlan_setup+0x1b0>
570: 48 8b 43 28 mov 0x28(%rbx),%rax
__skb_queue_head_init(&cell->napi_skbs);
netif_napi_add(dev, &cell->napi, gro_cell_poll, 64);
574: a8 01 test $0x1,%al
576: 75 93 jne 50b <vxlan_setup+0x14b>
gcells->cells = alloc_percpu(struct gro_cell);
if (!gcells->cells)
return -ENOMEM;
for_each_possible_cpu(i) {
struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
578: 0f 0b ud2
57a: 49 8d 84 24 a0 09 00 lea 0x9a0(%r12),%rax
581: 00
__skb_queue_head_init(&cell->napi_skbs);
netif_napi_add(dev, &cell->napi, gro_cell_poll, 64);
582: 49 8d 94 24 a0 11 00 lea 0x11a0(%r12),%rdx
589: 00
58a: 48 c7 00 00 00 00 00 movq $0x0,(%rax)
* the spinlock. It can also be used for on-stack sk_buff_head
* objects where the spinlock is known to not be used.
*/
static inline void __skb_queue_head_init(struct sk_buff_head *list)
{
list->prev = list->next = (struct sk_buff *)list;
591: 48 83 c0 08 add $0x8,%rax
list->qlen = 0;
595: 48 39 d0 cmp %rdx,%rax
598: 75 f0 jne 58a <vxlan_setup+0x1ca>
59a: 5b pop %rbx
59b: 41 5c pop %r12
59d: 41 5d pop %r13
59f: 5d pop %rbp
}
static __always_inline bool constant_test_bit(long nr, const volatile unsigned long *addr)
{
return ((1UL << (nr & (BITS_PER_LONG-1))) &
(addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
5a0: c3 retq
5a1: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
* Resume NAPI from being scheduled on this context.
* Must be paired with napi_disable.
*/
static inline void napi_enable(struct napi_struct *n)
{
BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
5a6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
5ad: 00 00 00
00000000000005b0 <vxlan_change_mtu>:
5b0: e8 00 00 00 00 callq 5b5 <vxlan_change_mtu+0x5>
5b5: 55 push %rbp
5b6: 48 89 e5 mov %rsp,%rbp
5b9: 41 54 push %r12
vxlan->dev = dev;
gro_cells_init(&vxlan->gro_cells, dev);
for (h = 0; h < FDB_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vxlan->fdb_head[h]);
5bb: 41 89 f4 mov %esi,%r12d
5be: 53 push %rbx
5bf: 48 89 fb mov %rdi,%rbx
5c2: 8b b7 a4 08 00 00 mov 0x8a4(%rdi),%esi
vxlan->dev = dev;
gro_cells_init(&vxlan->gro_cells, dev);
for (h = 0; h < FDB_HASH_SIZE; ++h)
5c8: 48 8b bf 78 08 00 00 mov 0x878(%rdi),%rdi
INIT_HLIST_HEAD(&vxlan->fdb_head[h]);
}
5cf: e8 00 00 00 00 callq 5d4 <vxlan_change_mtu+0x24>
5d4: 48 85 c0 test %rax,%rax
5d7: 74 30 je 609 <vxlan_change_mtu+0x59>
5d9: 8b 80 48 02 00 00 mov 0x248(%rax),%eax
5df: 8d 50 ba lea -0x46(%rax),%edx
dev->mtu = new_mtu;
return 0;
}
static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
{
5e2: 83 e8 32 sub $0x32,%eax
5e5: 66 83 bb 80 08 00 00 cmpw $0xa,0x880(%rbx)
5ec: 0a
5ed: 0f 44 c2 cmove %edx,%eax
5f0: 41 39 c4 cmp %eax,%r12d
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_rdst *dst = &vxlan->default_dst;
struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
5f3: 7f 1b jg 610 <vxlan_change_mtu+0x60>
5f5: 41 83 fc 43 cmp $0x43,%r12d
5f9: 7e 15 jle 610 <vxlan_change_mtu+0x60>
5fb: 44 89 a3 48 02 00 00 mov %r12d,0x248(%rbx)
602: 31 c0 xor %eax,%eax
struct net_device *lowerdev,
struct vxlan_rdst *dst, int new_mtu, bool strict)
{
int max_mtu = IP_MAX_MTU;
if (lowerdev)
604: 5b pop %rbx
605: 41 5c pop %r12
607: 5d pop %rbp
608: c3 retq
max_mtu = lowerdev->mtu;
609: b8 ff ff 00 00 mov $0xffff,%eax
60e: eb cf jmp 5df <vxlan_change_mtu+0x2f>
if (dst->remote_ip.sa.sa_family == AF_INET6)
max_mtu -= VXLAN6_HEADROOM;
610: b8 ea ff ff ff mov $0xffffffea,%eax
615: eb ed jmp 604 <vxlan_change_mtu+0x54>
617: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
61e: 00 00
0000000000000620 <vxlan_fdb_parse>:
max_mtu -= VXLAN_HEADROOM;
if (new_mtu < 68)
return -EINVAL;
if (new_mtu > max_mtu) {
620: e8 00 00 00 00 callq 625 <vxlan_fdb_parse+0x5>
625: 55 push %rbp
626: 48 89 e5 mov %rsp,%rbp
629: 41 56 push %r14
return -EINVAL;
new_mtu = max_mtu;
}
dev->mtu = new_mtu;
62b: 41 55 push %r13
62d: 41 54 push %r12
62f: 53 push %rbx
630: 49 89 f5 mov %rsi,%r13
return 0;
633: 48 89 fb mov %rdi,%rbx
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_rdst *dst = &vxlan->default_dst;
struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
dst->remote_ifindex);
return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
}
636: 49 89 d4 mov %rdx,%r12
static int __vxlan_change_mtu(struct net_device *dev,
struct net_device *lowerdev,
struct vxlan_rdst *dst, int new_mtu, bool strict)
{
int max_mtu = IP_MAX_MTU;
639: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
63d: 48 83 ec 40 sub $0x40,%rsp
if (new_mtu < 68)
return -EINVAL;
if (new_mtu > max_mtu) {
if (strict)
return -EINVAL;
641: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
648: 00 00
64a: 48 89 44 24 38 mov %rax,0x38(%rsp)
64f: 31 c0 xor %eax,%eax
}
static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
union vxlan_addr *ip, __be16 *port, __be32 *vni,
u32 *ifindex)
{
651: 48 8b 46 30 mov 0x30(%rsi),%rax
655: 48 8b 77 08 mov 0x8(%rdi),%rsi
659: 48 85 f6 test %rsi,%rsi
65c: 4c 8b b0 80 04 00 00 mov 0x480(%rax),%r14
663: 0f 84 ad 00 00 00 je 716 <vxlan_fdb_parse+0xf6>
669: 0f b7 06 movzwl (%rsi),%eax
66c: 83 e8 04 sub $0x4,%eax
66f: 83 f8 0f cmp $0xf,%eax
672: 0f 87 fd 00 00 00 ja 775 <vxlan_fdb_parse+0x155>
678: 83 f8 03 cmp $0x3,%eax
67b: 0f 86 68 01 00 00 jbe 7e9 <vxlan_fdb_parse+0x1c9>
}
static inline struct net *read_pnet(const possible_net_t *pnet)
{
#ifdef CONFIG_NET_NS
return pnet->net;
681: 8b 46 04 mov 0x4(%rsi),%eax
684: be 02 00 00 00 mov $0x2,%esi
struct net *net = dev_net(vxlan->dev);
int err;
if (tb[NDA_DST]) {
689: 66 89 32 mov %si,(%rdx)
68c: 89 42 04 mov %eax,0x4(%rdx)
68f: 48 8b 43 30 mov 0x30(%rbx),%rax
693: 48 85 c0 test %rax,%rax
696: 0f 84 b5 00 00 00 je 751 <vxlan_fdb_parse+0x131>
return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
}
static int vxlan_nla_get_addr(union vxlan_addr *ip, struct nlattr *nla)
{
if (nla_len(nla) >= sizeof(struct in6_addr)) {
69c: 66 83 38 06 cmpw $0x6,(%rax)
6a0: 75 6d jne 70f <vxlan_fdb_parse+0xef>
6a2: 0f b7 40 04 movzwl 0x4(%rax),%eax
6a6: 66 89 01 mov %ax,(%rcx)
ip->sin6.sin6_addr = nla_get_in6_addr(nla);
ip->sa.sa_family = AF_INET6;
return 0;
} else if (nla_len(nla) >= sizeof(__be32)) {
6a9: 48 8b 43 38 mov 0x38(%rbx),%rax
6ad: 48 85 c0 test %rax,%rax
6b0: 0f 84 b3 00 00 00 je 769 <vxlan_fdb_parse+0x149>
ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);
ip->sa.sa_family = AF_INET;
6b6: 66 83 38 08 cmpw $0x8,(%rax)
6ba: 75 53 jne 70f <vxlan_fdb_parse+0xef>
if (nla_len(nla) >= sizeof(struct in6_addr)) {
ip->sin6.sin6_addr = nla_get_in6_addr(nla);
ip->sa.sa_family = AF_INET6;
return 0;
} else if (nla_len(nla) >= sizeof(__be32)) {
ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);
6bc: 8b 40 04 mov 0x4(%rax),%eax
ip->sa.sa_family = AF_INET6;
#endif
}
}
if (tb[NDA_PORT]) {
6bf: 0f c8 bswap %eax
6c1: 41 89 00 mov %eax,(%r8)
6c4: 48 8b 43 40 mov 0x40(%rbx),%rax
6c8: 48 85 c0 test %rax,%rax
6cb: 0f 84 f4 00 00 00 je 7c5 <vxlan_fdb_parse+0x1a5>
if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
6d1: 66 83 38 08 cmpw $0x8,(%rax)
* nla_get_be16 - return payload of __be16 attribute
* @nla: __be16 netlink attribute
*/
static inline __be16 nla_get_be16(const struct nlattr *nla)
{
return *(__be16 *) nla_data(nla);
6d5: 75 38 jne 70f <vxlan_fdb_parse+0xef>
return -EINVAL;
*port = nla_get_be16(tb[NDA_PORT]);
6d7: 8b 70 04 mov 0x4(%rax),%esi
} else {
*port = vxlan->cfg.dst_port;
}
if (tb[NDA_VNI]) {
6da: 4c 89 f7 mov %r14,%rdi
6dd: 41 89 31 mov %esi,(%r9)
6e0: e8 00 00 00 00 callq 6e5 <vxlan_fdb_parse+0xc5>
6e5: 48 83 f8 01 cmp $0x1,%rax
if (nla_len(tb[NDA_VNI]) != sizeof(u32))
6e9: 19 c0 sbb %eax,%eax
6eb: 83 e0 9d and $0xffffff9d,%eax
return -EINVAL;
*vni = cpu_to_be32(nla_get_u32(tb[NDA_VNI]));
6ee: 48 8b 54 24 38 mov 0x38(%rsp),%rdx
6f3: 65 48 33 14 25 28 00 xor %gs:0x28,%rdx
6fa: 00 00
} else {
*vni = vxlan->default_dst.remote_vni;
}
if (tb[NDA_IFINDEX]) {
6fc: 0f 85 f1 00 00 00 jne 7f3 <vxlan_fdb_parse+0x1d3>
struct net_device *tdev;
if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
702: 48 8d 65 e0 lea -0x20(%rbp),%rsp
706: 5b pop %rbx
* nla_get_u32 - return payload of u32 attribute
* @nla: u32 netlink attribute
*/
static inline u32 nla_get_u32(const struct nlattr *nla)
{
return *(u32 *) nla_data(nla);
707: 41 5c pop %r12
709: 41 5d pop %r13
return -EINVAL;
*ifindex = nla_get_u32(tb[NDA_IFINDEX]);
tdev = __dev_get_by_index(net, *ifindex);
70b: 41 5e pop %r14
if (tb[NDA_IFINDEX]) {
struct net_device *tdev;
if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
return -EINVAL;
*ifindex = nla_get_u32(tb[NDA_IFINDEX]);
70d: 5d pop %rbp
70e: c3 retq
70f: b8 ea ff ff ff mov $0xffffffea,%eax
tdev = __dev_get_by_index(net, *ifindex);
714: eb d8 jmp 6ee <vxlan_fdb_parse+0xce>
return -EADDRNOTAVAIL;
} else {
*ifindex = 0;
}
return 0;
716: 66 41 83 7d 40 02 cmpw $0x2,0x40(%r13)
71c: 0f 84 b1 00 00 00 je 7d3 <vxlan_fdb_parse+0x1b3>
}
722: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 729 <vxlan_fdb_parse+0x109>
729: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 730 <vxlan_fdb_parse+0x110>
730: 49 89 44 24 08 mov %rax,0x8(%r12)
735: b8 0a 00 00 00 mov $0xa,%eax
73a: 49 89 54 24 10 mov %rdx,0x10(%r12)
}
}
if (tb[NDA_PORT]) {
if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
return -EINVAL;
73f: 66 41 89 04 24 mov %ax,(%r12)
744: 48 8b 43 30 mov 0x30(%rbx),%rax
err = vxlan_nla_get_addr(ip, tb[NDA_DST]);
if (err)
return err;
} else {
union vxlan_addr *remote = &vxlan->default_dst.remote_ip;
if (remote->sa.sa_family == AF_INET) {
748: 48 85 c0 test %rax,%rax
74b: 0f 85 4b ff ff ff jne 69c <vxlan_fdb_parse+0x7c>
751: 41 0f b7 85 3c 01 00 movzwl 0x13c(%r13),%eax
758: 00
ip->sin.sin_addr.s_addr = htonl(INADDR_ANY);
ip->sa.sa_family = AF_INET;
#if IS_ENABLED(CONFIG_IPV6)
} else {
ip->sin6.sin6_addr = in6addr_any;
759: 66 89 01 mov %ax,(%rcx)
75c: 48 8b 43 38 mov 0x38(%rbx),%rax
760: 48 85 c0 test %rax,%rax
763: 0f 85 4d ff ff ff jne 6b6 <vxlan_fdb_parse+0x96>
ip->sa.sa_family = AF_INET6;
769: 41 8b 45 60 mov 0x60(%r13),%eax
if (remote->sa.sa_family == AF_INET) {
ip->sin.sin_addr.s_addr = htonl(INADDR_ANY);
ip->sa.sa_family = AF_INET;
#if IS_ENABLED(CONFIG_IPV6)
} else {
ip->sin6.sin6_addr = in6addr_any;
76d: 41 89 00 mov %eax,(%r8)
ip->sa.sa_family = AF_INET6;
770: e9 4f ff ff ff jmpq 6c4 <vxlan_fdb_parse+0xa4>
#endif
}
}
if (tb[NDA_PORT]) {
775: 48 8d 7c 24 20 lea 0x20(%rsp),%rdi
77a: ba 10 00 00 00 mov $0x10,%edx
77f: 4c 89 4c 24 08 mov %r9,0x8(%rsp)
if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
return -EINVAL;
*port = nla_get_be16(tb[NDA_PORT]);
} else {
*port = vxlan->cfg.dst_port;
784: 4c 89 44 24 10 mov %r8,0x10(%rsp)
789: 48 89 4c 24 18 mov %rcx,0x18(%rsp)
}
if (tb[NDA_VNI]) {
78e: e8 00 00 00 00 callq 793 <vxlan_fdb_parse+0x173>
793: 48 8b 44 24 20 mov 0x20(%rsp),%rax
798: 48 8b 54 24 28 mov 0x28(%rsp),%rdx
if (nla_len(tb[NDA_VNI]) != sizeof(u32))
return -EINVAL;
*vni = cpu_to_be32(nla_get_u32(tb[NDA_VNI]));
} else {
*vni = vxlan->default_dst.remote_vni;
79d: bf 0a 00 00 00 mov $0xa,%edi
7a2: 66 41 89 3c 24 mov %di,(%r12)
*/
static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
{
struct in6_addr tmp;
nla_memcpy(&tmp, nla, sizeof(tmp));
7a7: 48 8b 4c 24 18 mov 0x18(%rsp),%rcx
7ac: 4c 8b 44 24 10 mov 0x10(%rsp),%r8
7b1: 4c 8b 4c 24 08 mov 0x8(%rsp),%r9
7b6: 49 89 44 24 08 mov %rax,0x8(%r12)
7bb: 49 89 54 24 10 mov %rdx,0x10(%r12)
7c0: e9 ca fe ff ff jmpq 68f <vxlan_fdb_parse+0x6f>
return tmp;
7c5: 41 c7 01 00 00 00 00 movl $0x0,(%r9)
7cc: 31 c0 xor %eax,%eax
static int vxlan_nla_get_addr(union vxlan_addr *ip, struct nlattr *nla)
{
if (nla_len(nla) >= sizeof(struct in6_addr)) {
ip->sin6.sin6_addr = nla_get_in6_addr(nla);
ip->sa.sa_family = AF_INET6;
7ce: e9 1b ff ff ff jmpq 6ee <vxlan_fdb_parse+0xce>
7d3: c7 42 04 00 00 00 00 movl $0x0,0x4(%rdx)
7da: ba 02 00 00 00 mov $0x2,%edx
7df: 66 41 89 14 24 mov %dx,(%r12)
7e4: e9 a6 fe ff ff jmpq 68f <vxlan_fdb_parse+0x6f>
}
static int vxlan_nla_get_addr(union vxlan_addr *ip, struct nlattr *nla)
{
if (nla_len(nla) >= sizeof(struct in6_addr)) {
ip->sin6.sin6_addr = nla_get_in6_addr(nla);
7e9: b8 9f ff ff ff mov $0xffffff9f,%eax
7ee: e9 fb fe ff ff jmpq 6ee <vxlan_fdb_parse+0xce>
7f3: e8 00 00 00 00 callq 7f8 <vxlan_fdb_parse+0x1d8>
*ifindex = nla_get_u32(tb[NDA_IFINDEX]);
tdev = __dev_get_by_index(net, *ifindex);
if (!tdev)
return -EADDRNOTAVAIL;
} else {
*ifindex = 0;
7f8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
7ff: 00
0000000000000800 <vxlan_get_drvinfo>:
}
return 0;
800: e8 00 00 00 00 callq 805 <vxlan_get_drvinfo+0x5>
if (err)
return err;
} else {
union vxlan_addr *remote = &vxlan->default_dst.remote_ip;
if (remote->sa.sa_family == AF_INET) {
ip->sin.sin_addr.s_addr = htonl(INADDR_ANY);
805: 55 push %rbp
806: 48 8d 7e 24 lea 0x24(%rsi),%rdi
ip->sa.sa_family = AF_INET;
80a: ba 20 00 00 00 mov $0x20,%edx
80f: 48 89 e5 mov %rsp,%rbp
812: 53 push %rbx
813: 48 89 f3 mov %rsi,%rbx
816: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
} else if (nla_len(nla) >= sizeof(__be32)) {
ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);
ip->sa.sa_family = AF_INET;
return 0;
} else {
return -EAFNOSUPPORT;
81d: e8 00 00 00 00 callq 822 <vxlan_get_drvinfo+0x22>
822: 48 8d 7b 04 lea 0x4(%rbx),%rdi
} else {
*ifindex = 0;
}
return 0;
}
826: ba 20 00 00 00 mov $0x20,%edx
82b: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
return 0;
}
static void vxlan_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
832: e8 00 00 00 00 callq 837 <vxlan_get_drvinfo+0x37>
strlcpy(drvinfo->version, VXLAN_VERSION, sizeof(drvinfo->version));
837: 5b pop %rbx
838: 5d pop %rbp
839: c3 retq
83a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000000840 <neigh_release>:
return 0;
}
static void vxlan_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
840: f0 ff 4f 30 lock decl 0x30(%rdi)
844: 74 01 je 847 <neigh_release+0x7>
strlcpy(drvinfo->version, VXLAN_VERSION, sizeof(drvinfo->version));
846: c3 retq
847: 55 push %rbp
848: 48 89 e5 mov %rsp,%rbp
84b: e8 00 00 00 00 callq 850 <neigh_release+0x10>
850: 5d pop %rbp
851: c3 retq
strlcpy(drvinfo->driver, "vxlan", sizeof(drvinfo->driver));
852: 0f 1f 40 00 nopl 0x0(%rax)
856: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
85d: 00 00 00
0000000000000860 <vxlan_gro_complete>:
860: e8 00 00 00 00 callq 865 <vxlan_gro_complete+0x5>
865: 55 push %rbp
866: 48 89 f7 mov %rsi,%rdi
}
869: 8d 72 08 lea 0x8(%rdx),%esi
86c: 48 89 e5 mov %rsp,%rbp
86f: e8 00 00 00 00 callq 874 <vxlan_gro_complete+0x14>
* returns true if the result is 0, or false for all other
* cases.
*/
static __always_inline bool atomic_dec_and_test(atomic_t *v)
{
GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", e);
874: 5d pop %rbp
875: c3 retq
876: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
87d: 00 00 00
0000000000000880 <vxlan_init>:
static inline void neigh_release(struct neighbour *neigh)
{
if (atomic_dec_and_test(&neigh->refcnt))
neigh_destroy(neigh);
}
880: e8 00 00 00 00 callq 885 <vxlan_init+0x5>
885: 55 push %rbp
886: ba c0 00 40 02 mov $0x24000c0,%edx
88b: be 08 00 00 00 mov $0x8,%esi
return pp;
}
static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
{
890: 48 89 e5 mov %rsp,%rbp
893: 41 54 push %r12
895: 53 push %rbx
896: 49 89 fc mov %rdi,%r12
/* Sets 'skb->inner_mac_header' since we are always called with
* 'skb->encapsulation' set.
*/
return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr));
899: bf 20 00 00 00 mov $0x20,%edi
return pp;
}
static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
{
89e: e8 00 00 00 00 callq 8a3 <vxlan_init+0x23>
/* Sets 'skb->inner_mac_header' since we are always called with
* 'skb->encapsulation' set.
*/
return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr));
8a3: 48 85 c0 test %rax,%rax
}
8a6: 74 38 je 8e0 <vxlan_init+0x60>
8a8: 48 89 c3 mov %rax,%rbx
8ab: ba ff ff ff ff mov $0xffffffff,%edx
spin_unlock(&vn->sock_lock);
}
/* Setup stats when device is created */
static int vxlan_init(struct net_device *dev)
{
8b0: 83 c2 01 add $0x1,%edx
8b3: be 00 01 00 00 mov $0x100,%esi
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
8b8: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
8bf: 48 63 d2 movslq %edx,%rdx
spin_unlock(&vn->sock_lock);
}
/* Setup stats when device is created */
static int vxlan_init(struct net_device *dev)
{
8c2: e8 00 00 00 00 callq 8c7 <vxlan_init+0x47>
8c7: 3b 05 00 00 00 00 cmp 0x0(%rip),%eax # 8cd <vxlan_init+0x4d>
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
8cd: 89 c2 mov %eax,%edx
8cf: 7c df jl 8b0 <vxlan_init+0x30>
8d1: 49 89 9c 24 88 04 00 mov %rbx,0x488(%r12)
8d8: 00
8d9: 31 c0 xor %eax,%eax
8db: 5b pop %rbx
8dc: 41 5c pop %r12
8de: 5d pop %rbp
8df: c3 retq
8e0: 5b pop %rbx
8e1: 49 c7 84 24 88 04 00 movq $0x0,0x488(%r12)
8e8: 00 00 00 00 00
8ed: b8 f4 ff ff ff mov $0xfffffff4,%eax
8f2: 41 5c pop %r12
8f4: 5d pop %rbp
8f5: c3 retq
8f6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
8fd: 00 00 00
0000000000000900 <vxlan_dellink>:
900: e8 00 00 00 00 callq 905 <vxlan_dellink+0x5>
905: 55 push %rbp
906: 48 89 e5 mov %rsp,%rbp
if (!dev->tstats)
return -ENOMEM;
return 0;
909: 41 56 push %r14
}
90b: 41 55 push %r13
90d: 41 54 push %r12
90f: 53 push %rbx
910: 49 89 fd mov %rdi,%r13
}
/* Setup stats when device is created */
static int vxlan_init(struct net_device *dev)
{
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
913: 48 8b 87 78 08 00 00 mov 0x878(%rdi),%rax
91a: 49 89 f6 mov %rsi,%r14
if (!dev->tstats)
return -ENOMEM;
91d: 48 8b 90 88 14 00 00 mov 0x1488(%rax),%rdx
return 0;
}
924: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 92a <vxlan_dellink+0x2a>
92a: 83 e8 01 sub $0x1,%eax
92d: 48 98 cltq
92f: 48 8b 5c c2 18 mov 0x18(%rdx,%rax,8),%rbx
return vxlan_dev_configure(src_net, dev, &conf);
}
static void vxlan_dellink(struct net_device *dev, struct list_head *head)
{
934: 48 81 c3 10 08 00 00 add $0x810,%rbx
93b: 48 89 df mov %rbx,%rdi
93e: e8 00 00 00 00 callq 943 <vxlan_dellink+0x43>
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
943: 49 8b 85 48 08 00 00 mov 0x848(%r13),%rax
return vxlan_dev_configure(src_net, dev, &conf);
}
static void vxlan_dellink(struct net_device *dev, struct list_head *head)
{
94a: 48 85 c0 test %rax,%rax
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
94d: 74 24 je 973 <vxlan_dellink+0x73>
94f: 49 8b 95 40 08 00 00 mov 0x840(%r13),%rdx
956: 48 85 d2 test %rdx,%rdx
959: 48 89 10 mov %rdx,(%rax)
95c: 74 04 je 962 <vxlan_dellink+0x62>
95e: 48 89 42 08 mov %rax,0x8(%rdx)
raw_spin_lock_init(&(_lock)->rlock); \
} while (0)
static __always_inline void spin_lock(spinlock_t *lock)
{
raw_spin_lock(&lock->rlock);
962: 48 b8 00 02 00 00 00 movabs $0xdead000000000200,%rax
969: 00 ad de
96c: 49 89 85 48 08 00 00 mov %rax,0x848(%r13)
973: 48 89 df mov %rbx,%rdi
976: ff 14 25 00 00 00 00 callq *0x0
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
spin_lock(&vn->sock_lock);
if (!hlist_unhashed(&vxlan->hlist))
97d: 49 83 bd 30 09 00 00 cmpq $0x0,0x930(%r13)
984: 00
return !READ_ONCE(h->first);
}
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
985: 41 bc ff ff ff ff mov $0xffffffff,%r12d
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
98b: 0f 84 8a 00 00 00 je a1b <vxlan_dellink+0x11b>
struct hlist_node **pprev = n->pprev;
WRITE_ONCE(*pprev, next);
if (next)
next->pprev = pprev;
991: 41 8d 54 24 01 lea 0x1(%r12),%edx
* hlist_for_each_entry().
*/
static inline void hlist_del_rcu(struct hlist_node *n)
{
__hlist_del(n);
n->pprev = LIST_POISON2;
996: be 00 01 00 00 mov $0x100,%esi
99b: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
9a2: 48 63 d2 movslq %edx,%rdx
PVOP_VCALL2(pv_lock_ops.queued_spin_lock_slowpath, lock, val);
}
static __always_inline void pv_queued_spin_unlock(struct qspinlock *lock)
{
PVOP_VCALLEE1(pv_lock_ops.queued_spin_unlock, lock);
9a5: e8 00 00 00 00 callq 9aa <vxlan_dellink+0xaa>
9aa: 3b 05 00 00 00 00 cmp 0x0(%rip),%eax # 9b0 <vxlan_dellink+0xb0>
static inline void gro_cells_destroy(struct gro_cells *gcells)
{
int i;
if (!gcells->cells)
9b0: 41 89 c4 mov %eax,%r12d
9b3: 7d 4f jge a04 <vxlan_dellink+0x104>
9b5: 48 98 cltq
9b7: 49 8b 9d 30 09 00 00 mov 0x930(%r13),%rbx
9be: 48 03 1c c5 00 00 00 add 0x0(,%rax,8),%rbx
9c5: 00
9c6: 48 8d 7b 18 lea 0x18(%rbx),%rdi
9ca: e8 00 00 00 00 callq 9cf <vxlan_dellink+0xcf>
9cf: 48 8b 3b mov (%rbx),%rdi
9d2: 48 39 fb cmp %rdi,%rbx
9d5: 74 ba je 991 <vxlan_dellink+0x91>
9d7: 48 85 ff test %rdi,%rdi
return;
for_each_possible_cpu(i) {
9da: 74 b5 je 991 <vxlan_dellink+0x91>
9dc: 83 6b 10 01 subl $0x1,0x10(%rbx)
9e0: 48 8b 17 mov (%rdi),%rdx
9e3: 48 8b 47 08 mov 0x8(%rdi),%rax
struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
9e7: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
9ee: 48 c7 47 08 00 00 00 movq $0x0,0x8(%rdi)
9f5: 00
netif_napi_del(&cell->napi);
9f6: 48 89 42 08 mov %rax,0x8(%rdx)
9fa: 48 89 10 mov %rdx,(%rax)
9fd: e8 00 00 00 00 callq a02 <vxlan_dellink+0x102>
*/
static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
{
struct sk_buff *skb = list_->next;
if (skb == (struct sk_buff *)list_)
a02: eb cb jmp 9cf <vxlan_dellink+0xcf>
a04: 49 8b bd 30 09 00 00 mov 0x930(%r13),%rdi
*/
struct sk_buff *skb_dequeue(struct sk_buff_head *list);
static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
{
struct sk_buff *skb = skb_peek(list);
if (skb)
a0b: e8 00 00 00 00 callq a10 <vxlan_dellink+0x110>
static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
{
struct sk_buff *next, *prev;
list->qlen--;
next = skb->next;
a10: 49 c7 85 30 09 00 00 movq $0x0,0x930(%r13)
a17: 00 00 00 00
prev = skb->prev;
skb->next = skb->prev = NULL;
a1b: 49 8b 85 58 08 00 00 mov 0x858(%r13),%rax
a22: 49 8b 95 50 08 00 00 mov 0x850(%r13),%rdx
next->prev = prev;
a29: 4c 89 f6 mov %r14,%rsi
prev->next = next;
a2c: 4c 89 ef mov %r13,%rdi
void skb_queue_purge(struct sk_buff_head *list);
static inline void __skb_queue_purge(struct sk_buff_head *list)
{
struct sk_buff *skb;
while ((skb = __skb_dequeue(list)) != NULL)
kfree_skb(skb);
a2f: 48 89 42 08 mov %rax,0x8(%rdx)
a33: 48 89 10 mov %rdx,(%rax)
__skb_queue_purge(&cell->napi_skbs);
}
free_percpu(gcells->cells);
a36: 48 b8 00 01 00 00 00 movabs $0xdead000000000100,%rax
a3d: 00 ad de
gcells->cells = NULL;
a40: 49 89 85 50 08 00 00 mov %rax,0x850(%r13)
a47: 48 b8 00 02 00 00 00 movabs $0xdead000000000200,%rax
a4e: 00 ad de
__list_del(entry->prev, entry->next);
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
a51: 49 89 85 58 08 00 00 mov %rax,0x858(%r13)
a58: e8 00 00 00 00 callq a5d <vxlan_dellink+0x15d>
hlist_del_rcu(&vxlan->hlist);
spin_unlock(&vn->sock_lock);
gro_cells_destroy(&vxlan->gro_cells);
list_del(&vxlan->next);
unregister_netdevice_queue(dev, head);
a5d: 5b pop %rbx
a5e: 41 5c pop %r12
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
a60: 41 5d pop %r13
a62: 41 5e pop %r14
a64: 5d pop %rbp
a65: c3 retq
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
a66: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
a6d: 00 00 00
0000000000000a70 <vxlan6_get_route>:
a70: e8 00 00 00 00 callq a75 <vxlan6_get_route+0x5>
a75: 55 push %rbp
a76: 48 89 e5 mov %rsp,%rbp
entry->prev = LIST_POISON2;
a79: 41 57 push %r15
a7b: 41 56 push %r14
a7d: 41 55 push %r13
a7f: 41 54 push %r12
a81: 49 89 f7 mov %rsi,%r15
a84: 53 push %rbx
a85: 89 cb mov %ecx,%ebx
a87: 49 89 fe mov %rdi,%r14
a8a: 48 83 ec 68 sub $0x68,%rsp
}
a8e: 8b b6 b4 00 00 00 mov 0xb4(%rsi),%esi
a94: 4c 8b 65 10 mov 0x10(%rbp),%r12
a98: 65 48 8b 0c 25 28 00 mov %gs:0x28,%rcx
a9f: 00 00
__be32 label,
const struct in6_addr *daddr,
struct in6_addr *saddr,
struct dst_cache *dst_cache,
const struct ip_tunnel_info *info)
{
aa1: 48 89 4c 24 60 mov %rcx,0x60(%rsp)
aa6: 31 c9 xor %ecx,%ecx
aa8: 4c 8b 6d 18 mov 0x18(%rbp),%r13
aac: 48 8b 45 20 mov 0x20(%rbp),%rax
ab0: 85 f6 test %esi,%esi
ab2: 75 51 jne b05 <vxlan6_get_route+0x95>
ab4: 48 85 c0 test %rax,%rax
ab7: 74 48 je b01 <vxlan6_get_route+0x91>
ab9: f6 40 28 20 testb $0x20,0x28(%rax)
abd: 75 46 jne b05 <vxlan6_get_route+0x95>
abf: 4c 89 e6 mov %r12,%rsi
ac2: 4c 89 ef mov %r13,%rdi
ac5: 4c 89 0c 24 mov %r9,(%rsp)
ac9: 44 89 44 24 08 mov %r8d,0x8(%rsp)
ace: 89 54 24 0c mov %edx,0xc(%rsp)
ad2: e8 00 00 00 00 callq ad7 <vxlan6_get_route+0x67>
ad7: 48 85 c0 test %rax,%rax
ada: 48 89 44 24 10 mov %rax,0x10(%rsp)
adf: 8b 54 24 0c mov 0xc(%rsp),%edx
static inline bool
ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
if (skb->mark)
ae3: 44 8b 44 24 08 mov 0x8(%rsp),%r8d
return false;
if (!info)
ae8: 4c 8b 0c 24 mov (%rsp),%r9
return true;
if (info->key.tun_flags & TUNNEL_NOCACHE)
aec: 0f 85 ac 00 00 00 jne b9e <vxlan6_get_route+0x12e>
int err;
if (tos && !info)
use_cache = false;
if (use_cache) {
ndst = dst_cache_get_ip6(dst_cache, saddr);
af2: 41 8b b7 b4 00 00 00 mov 0xb4(%r15),%esi
af9: 41 bf 01 00 00 00 mov $0x1,%r15d
aff: eb 07 jmp b08 <vxlan6_get_route+0x98>
b01: 84 db test %bl,%bl
b03: 74 ba je abf <vxlan6_get_route+0x4f>
b05: 45 31 ff xor %r15d,%r15d
if (ndst)
b08: 4c 8d 54 24 18 lea 0x18(%rsp),%r10
int err;
if (tos && !info)
use_cache = false;
if (use_cache) {
ndst = dst_cache_get_ip6(dst_cache, saddr);
b0d: 31 c0 xor %eax,%eax
if (ndst)
b0f: b9 09 00 00 00 mov $0x9,%ecx
b14: 83 e3 1e and $0x1e,%ebx
b17: 4c 89 d7 mov %r10,%rdi
b1a: c1 e3 14 shl $0x14,%ebx
b1d: f3 48 ab rep stos %rax,%es:(%rdi)
b20: 49 8b 01 mov (%r9),%rax
b23: 89 54 24 18 mov %edx,0x18(%rsp)
b27: 0f cb bswap %ebx
b29: 49 8b 51 08 mov 0x8(%r9),%rdx
b2d: 41 09 d8 or %ebx,%r8d
b30: 89 74 24 20 mov %esi,0x20(%rsp)
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
struct dst_entry *ndst;
struct flowi6 fl6;
int err;
if (tos && !info)
b34: 44 89 44 24 58 mov %r8d,0x58(%rsp)
ndst = dst_cache_get_ip6(dst_cache, saddr);
if (ndst)
return ndst;
}
memset(&fl6, 0, sizeof(fl6));
b39: c6 44 24 26 11 movb $0x11,0x26(%rsp)
b3e: 4c 89 d1 mov %r10,%rcx
b41: 48 89 44 24 38 mov %rax,0x38(%rsp)
return ntohl(flowinfo & IPV6_TCLASS_MASK) >> IPV6_TCLASS_SHIFT;
}
static inline __be32 ip6_make_flowinfo(unsigned int tclass, __be32 flowlabel)
{
return htonl(tclass << IPV6_TCLASS_SHIFT) | flowlabel;
b46: 49 8b 04 24 mov (%r12),%rax
b4a: 48 89 54 24 40 mov %rdx,0x40(%rsp)
b4f: 49 8b 54 24 08 mov 0x8(%r12),%rdx
fl6.flowi6_oif = oif;
b54: 49 8b 7e 38 mov 0x38(%r14),%rdi
b58: 48 89 44 24 48 mov %rax,0x48(%rsp)
fl6.daddr = *daddr;
fl6.saddr = *saddr;
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
b5d: 49 8b 46 28 mov 0x28(%r14),%rax
fl6.flowi6_mark = skb->mark;
b61: 48 89 54 24 50 mov %rdx,0x50(%rsp)
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = oif;
fl6.daddr = *daddr;
fl6.saddr = *saddr;
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
b66: 48 8d 54 24 10 lea 0x10(%rsp),%rdx
fl6.flowi6_mark = skb->mark;
fl6.flowi6_proto = IPPROTO_UDP;
b6b: 48 8b 40 10 mov 0x10(%rax),%rax
err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
b6f: 48 8b 70 20 mov 0x20(%rax),%rsi
return ndst;
}
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = oif;
fl6.daddr = *daddr;
b73: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # b7a <vxlan6_get_route+0x10a>
b7a: ff 50 10 callq *0x10(%rax)
b7d: 85 c0 test %eax,%eax
fl6.saddr = *saddr;
b7f: 78 3c js bbd <vxlan6_get_route+0x14d>
b81: 48 8b 44 24 48 mov 0x48(%rsp),%rax
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
fl6.flowi6_mark = skb->mark;
fl6.flowi6_proto = IPPROTO_UDP;
err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
b86: 48 8b 54 24 50 mov 0x50(%rsp),%rdx
}
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = oif;
fl6.daddr = *daddr;
fl6.saddr = *saddr;
b8b: 45 84 ff test %r15b,%r15b
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
fl6.flowi6_mark = skb->mark;
fl6.flowi6_proto = IPPROTO_UDP;
err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
vxlan->vn6_sock->sock->sk,
b8e: 49 89 04 24 mov %rax,(%r12)
}
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = oif;
fl6.daddr = *daddr;
fl6.saddr = *saddr;
b92: 49 89 54 24 08 mov %rdx,0x8(%r12)
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tos), label);
fl6.flowi6_mark = skb->mark;
fl6.flowi6_proto = IPPROTO_UDP;
err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
b97: 75 28 jne bc1 <vxlan6_get_route+0x151>
b99: 48 8b 44 24 10 mov 0x10(%rsp),%rax
b9e: 48 8b 4c 24 60 mov 0x60(%rsp),%rcx
ba3: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
baa: 00 00
bac: 75 25 jne bd3 <vxlan6_get_route+0x163>
vxlan->vn6_sock->sock->sk,
&ndst, &fl6);
if (err < 0)
bae: 48 83 c4 68 add $0x68,%rsp
return ERR_PTR(err);
*saddr = fl6.saddr;
bb2: 5b pop %rbx
bb3: 41 5c pop %r12
bb5: 41 5d pop %r13
bb7: 41 5e pop %r14
bb9: 41 5f pop %r15
if (use_cache)
bbb: 5d pop %rbp
bbc: c3 retq
bbd: 48 98 cltq
vxlan->vn6_sock->sock->sk,
&ndst, &fl6);
if (err < 0)
return ERR_PTR(err);
*saddr = fl6.saddr;
bbf: eb dd jmp b9e <vxlan6_get_route+0x12e>
bc1: 48 8b 74 24 10 mov 0x10(%rsp),%rsi
bc6: 4c 89 e2 mov %r12,%rdx
if (use_cache)
dst_cache_set_ip6(dst_cache, ndst, saddr);
return ndst;
bc9: 4c 89 ef mov %r13,%rdi
bcc: e8 00 00 00 00 callq bd1 <vxlan6_get_route+0x161>
}
bd1: eb c6 jmp b99 <vxlan6_get_route+0x129>
bd3: e8 00 00 00 00 callq bd8 <vxlan6_get_route+0x168>
bd8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
bdf: 00
0000000000000be0 <__vxlan_sock_release_prep>:
be0: e8 00 00 00 00 callq be5 <__vxlan_sock_release_prep+0x5>
be5: 48 85 ff test %rdi,%rdi
be8: 0f 84 92 00 00 00 je c80 <__vxlan_sock_release_prep+0xa0>
#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)
static inline void * __must_check ERR_PTR(long error)
{
return (void *) error;
bee: f0 ff 8f 18 20 00 00 lock decl 0x2018(%rdi)
if (err < 0)
return ERR_PTR(err);
*saddr = fl6.saddr;
if (use_cache)
dst_cache_set_ip6(dst_cache, ndst, saddr);
bf5: 74 03 je bfa <__vxlan_sock_release_prep+0x1a>
bf7: 31 c0 xor %eax,%eax
bf9: c3 retq
bfa: 55 push %rbp
bfb: 48 89 e5 mov %rsp,%rbp
bfe: 41 54 push %r12
c00: 53 push %rbx
c01: 48 8b 47 10 mov 0x10(%rdi),%rax
return ndst;
}
c05: 48 89 fb mov %rdi,%rbx
c08: 48 8b 40 20 mov 0x20(%rax),%rax
c0c: 48 8b 40 30 mov 0x30(%rax),%rax
return false;
}
static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
{
c10: 48 8b 90 88 14 00 00 mov 0x1488(%rax),%rdx
struct vxlan_net *vn;
if (!vs)
c17: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # c1d <__vxlan_sock_release_prep+0x3d>
c1d: 83 e8 01 sub $0x1,%eax
c20: 48 98 cltq
c22: 4c 8b 64 c2 18 mov 0x18(%rdx,%rax,8),%r12
return false;
if (!atomic_dec_and_test(&vs->refcnt))
return false;
c27: 49 81 c4 10 08 00 00 add $0x810,%r12
return false;
}
static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
{
c2e: 4c 89 e7 mov %r12,%rdi
if (!vs)
return false;
if (!atomic_dec_and_test(&vs->refcnt))
return false;
vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id);
c31: e8 00 00 00 00 callq c36 <__vxlan_sock_release_prep+0x56>
c36: 48 8b 03 mov (%rbx),%rax
c39: 48 8b 53 08 mov 0x8(%rbx),%rdx
c3d: 48 85 c0 test %rax,%rax
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
c40: 48 89 02 mov %rax,(%rdx)
c43: 74 04 je c49 <__vxlan_sock_release_prep+0x69>
c45: 48 89 50 08 mov %rdx,0x8(%rax)
c49: 8b b3 1c 20 00 00 mov 0x201c(%rbx),%esi
c4f: 48 8b 7b 10 mov 0x10(%rbx),%rdi
c53: 48 b8 00 02 00 00 00 movabs $0xdead000000000200,%rax
c5a: 00 ad de
c5d: 48 89 43 08 mov %rax,0x8(%rbx)
c61: c1 ee 0d shr $0xd,%esi
c64: 83 e6 02 and $0x2,%esi
return !READ_ONCE(h->first);
}
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
c67: e8 00 00 00 00 callq c6c <__vxlan_sock_release_prep+0x8c>
struct hlist_node **pprev = n->pprev;
c6c: 4c 89 e7 mov %r12,%rdi
WRITE_ONCE(*pprev, next);
if (next)
c6f: ff 14 25 00 00 00 00 callq *0x0
next->pprev = pprev;
c76: b8 01 00 00 00 mov $0x1,%eax
spin_lock(&vn->sock_lock);
hlist_del_rcu(&vs->hlist);
udp_tunnel_notify_del_rx_port(vs->sock,
c7b: 5b pop %rbx
c7c: 41 5c pop %r12
c7e: 5d pop %rbp
c7f: c3 retq
c80: 31 c0 xor %eax,%eax
c82: c3 retq
c83: 0f 1f 00 nopl (%rax)
c86: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
c8d: 00 00 00
0000000000000c90 <vxlan_sock_release.isra.44>:
c90: e8 00 00 00 00 callq c95 <vxlan_sock_release.isra.44+0x5>
c95: 55 push %rbp
c96: 48 89 e5 mov %rsp,%rbp
c99: 41 56 push %r14
c9b: 41 55 push %r13
c9d: 41 54 push %r12
c9f: 49 89 fc mov %rdi,%r12
ca2: 53 push %rbx
ca3: 48 8b 3f mov (%rdi),%rdi
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
spin_release(&lock->dep_map, 1, _RET_IP_);
do_raw_spin_unlock(lock);
preempt_enable();
ca6: 48 89 f3 mov %rsi,%rbx
ca9: e8 32 ff ff ff callq be0 <__vxlan_sock_release_prep>
UDP_TUNNEL_TYPE_VXLAN_GPE :
UDP_TUNNEL_TYPE_VXLAN);
spin_unlock(&vn->sock_lock);
return true;
}
cae: 48 8b 3b mov (%rbx),%rdi
static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
{
struct vxlan_net *vn;
if (!vs)
return false;
cb1: 41 89 c6 mov %eax,%r14d
cb4: e8 27 ff ff ff callq be0 <__vxlan_sock_release_prep>
cb9: 41 89 c5 mov %eax,%r13d
cbc: e8 00 00 00 00 callq cc1 <vxlan_sock_release.isra.44+0x31>
spin_unlock(&vn->sock_lock);
return true;
}
static void vxlan_sock_release(struct vxlan_dev *vxlan)
cc1: 45 84 f6 test %r14b,%r14b
cc4: 75 22 jne ce8 <vxlan_sock_release.isra.44+0x58>
cc6: 45 84 ed test %r13b,%r13b
cc9: 74 14 je cdf <vxlan_sock_release.isra.44+0x4f>
ccb: 48 8b 03 mov (%rbx),%rax
cce: 48 8b 78 10 mov 0x10(%rax),%rdi
cd2: e8 00 00 00 00 callq cd7 <vxlan_sock_release.isra.44+0x47>
cd7: 48 8b 3b mov (%rbx),%rdi
{
bool ipv4 = __vxlan_sock_release_prep(vxlan->vn4_sock);
cda: e8 00 00 00 00 callq cdf <vxlan_sock_release.isra.44+0x4f>
#if IS_ENABLED(CONFIG_IPV6)
bool ipv6 = __vxlan_sock_release_prep(vxlan->vn6_sock);
cdf: 5b pop %rbx
ce0: 41 5c pop %r12
return true;
}
static void vxlan_sock_release(struct vxlan_dev *vxlan)
{
bool ipv4 = __vxlan_sock_release_prep(vxlan->vn4_sock);
ce2: 41 5d pop %r13
#if IS_ENABLED(CONFIG_IPV6)
bool ipv6 = __vxlan_sock_release_prep(vxlan->vn6_sock);
ce4: 41 5e pop %r14
ce6: 5d pop %rbp
ce7: c3 retq
ce8: 49 8b 04 24 mov (%r12),%rax
#endif
synchronize_net();
cec: 48 8b 78 10 mov 0x10(%rax),%rdi
cf0: e8 00 00 00 00 callq cf5 <vxlan_sock_release.isra.44+0x65>
if (ipv4) {
cf5: 49 8b 3c 24 mov (%r12),%rdi
udp_tunnel_sock_release(vxlan->vn4_sock->sock);
kfree(vxlan->vn4_sock);
}
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6) {
cf9: e8 00 00 00 00 callq cfe <vxlan_sock_release.isra.44+0x6e>
udp_tunnel_sock_release(vxlan->vn6_sock->sock);
cfe: eb c6 jmp cc6 <vxlan_sock_release.isra.44+0x36>
0000000000000d00 <vxlan_netdevice_event>:
d00: e8 00 00 00 00 callq d05 <vxlan_netdevice_event+0x5>
d05: 55 push %rbp
d06: 48 89 e5 mov %rsp,%rbp
kfree(vxlan->vn6_sock);
d09: 41 56 push %r14
d0b: 41 55 push %r13
d0d: 41 54 push %r12
}
#endif
}
d0f: 53 push %rbx
d10: 48 83 ec 18 sub $0x18,%rsp
d14: 4c 8b 22 mov (%rdx),%r12
d17: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
d1e: 00 00
#endif
synchronize_net();
if (ipv4) {
udp_tunnel_sock_release(vxlan->vn4_sock->sock);
d20: 48 89 45 d8 mov %rax,-0x28(%rbp)
d24: 31 c0 xor %eax,%eax
kfree(vxlan->vn4_sock);
d26: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # d2c <vxlan_netdevice_event+0x2c>
d2c: 49 8b 94 24 80 04 00 mov 0x480(%r12),%rdx
d33: 00
unregister_netdevice_many(&list_kill);
}
static int vxlan_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
d34: 83 e8 01 sub $0x1,%eax
d37: 48 83 fe 06 cmp $0x6,%rsi
d3b: 48 8b 8a 88 14 00 00 mov 0x1488(%rdx),%rcx
d42: 0f 84 8a 00 00 00 je dd2 <vxlan_netdevice_event+0xd2>
d48: 48 83 fe 1c cmp $0x1c,%rsi
d4c: 74 22 je d70 <vxlan_netdevice_event+0x70>
d4e: 31 c0 xor %eax,%eax
d50: 48 8b 4d d8 mov -0x28(%rbp),%rcx
d54: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
d5b: 00 00
d5d: 0f 85 d7 00 00 00 jne e3a <vxlan_netdevice_event+0x13a>
d63: 48 83 c4 18 add $0x18,%rsp
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
if (event == NETDEV_UNREGISTER)
d67: 5b pop %rbx
d68: 41 5c pop %r12
d6a: 41 5d pop %r13
d6c: 41 5e pop %r14
d6e: 5d pop %rbp
d6f: c3 retq
d70: 48 8b 92 88 14 00 00 mov 0x1488(%rdx),%rdx
d77: 48 98 cltq
vxlan_handle_lowerdev_unregister(vn, dev);
else if (event == NETDEV_UDP_TUNNEL_PUSH_INFO)
d79: 4c 8b 6c c2 18 mov 0x18(%rdx,%rax,8),%r13
vxlan_push_rx_ports(dev);
return NOTIFY_DONE;
}
d7e: 4d 8d b5 10 08 00 00 lea 0x810(%r13),%r14
d85: 49 83 c5 10 add $0x10,%r13
d89: 4c 89 f7 mov %r14,%rdi
d8c: e8 00 00 00 00 callq d91 <vxlan_netdevice_event+0x91>
d91: 49 8b 5d 00 mov 0x0(%r13),%rbx
d95: 48 85 db test %rbx,%rbx
d98: 74 20 je dba <vxlan_netdevice_event+0xba>
d9a: 8b 93 1c 20 00 00 mov 0x201c(%rbx),%edx
da0: 48 8b 73 10 mov 0x10(%rbx),%rsi
da4: 4c 89 e7 mov %r12,%rdi
da7: c1 ea 0d shr $0xd,%edx
daa: 83 e2 02 and $0x2,%edx
dad: e8 00 00 00 00 callq db2 <vxlan_netdevice_event+0xb2>
db2: 48 8b 1b mov (%rbx),%rbx
db5: 48 85 db test %rbx,%rbx
db8: 75 e0 jne d9a <vxlan_netdevice_event+0x9a>
dba: 49 83 c5 08 add $0x8,%r13
dbe: 4d 39 ee cmp %r13,%r14
dc1: 75 ce jne d91 <vxlan_netdevice_event+0x91>
dc3: 4c 89 f7 mov %r14,%rdi
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
unsigned int i;
spin_lock(&vn->sock_lock);
for (i = 0; i < PORT_HASH_SIZE; ++i) {
hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist)
dc6: ff 14 25 00 00 00 00 callq *0x0
udp_tunnel_push_rx_port(dev, vs->sock,
dcd: e9 7c ff ff ff jmpq d4e <vxlan_netdevice_event+0x4e>
dd2: 48 98 cltq
dd4: 4c 8d 75 c8 lea -0x38(%rbp),%r14
dd8: 4c 8b 6c c1 18 mov 0x18(%rcx,%rax,8),%r13
ddd: 4c 89 75 c8 mov %r14,-0x38(%rbp)
de1: 4c 89 75 d0 mov %r14,-0x30(%rbp)
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
unsigned int i;
spin_lock(&vn->sock_lock);
for (i = 0; i < PORT_HASH_SIZE; ++i) {
hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist)
de5: 49 8b 45 00 mov 0x0(%r13),%rax
de9: 48 8b 08 mov (%rax),%rcx
dec: 49 39 c5 cmp %rax,%r13
struct net *net = dev_net(dev);
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
unsigned int i;
spin_lock(&vn->sock_lock);
for (i = 0; i < PORT_HASH_SIZE; ++i) {
def: 48 8d 50 f0 lea -0x10(%rax),%rdx
df3: 48 8d 59 f0 lea -0x10(%rcx),%rbx
df7: 75 19 jne e12 <vxlan_netdevice_event+0x112>
df9: eb 32 jmp e2d <vxlan_netdevice_event+0x12d>
dfb: 48 8b 43 10 mov 0x10(%rbx),%rax
dff: 48 8d 4b 10 lea 0x10(%rbx),%rcx
e03: 48 89 da mov %rbx,%rdx
static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn,
struct net_device *dev)
{
struct vxlan_dev *vxlan, *next;
LIST_HEAD(list_kill);
e06: 48 83 e8 10 sub $0x10,%rax
e0a: 49 39 cd cmp %rcx,%r13
e0d: 74 1e je e2d <vxlan_netdevice_event+0x12d>
e0f: 48 89 c3 mov %rax,%rbx
e12: 41 8b 84 24 28 01 00 mov 0x128(%r12),%eax
e19: 00
list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
e1a: 39 42 64 cmp %eax,0x64(%rdx)
e1d: 75 dc jne dfb <vxlan_netdevice_event+0xfb>
e1f: 48 8b 7a 30 mov 0x30(%rdx),%rdi
e23: 4c 89 f6 mov %r14,%rsi
e26: e8 d5 fa ff ff callq 900 <vxlan_dellink>
e2b: eb ce jmp dfb <vxlan_netdevice_event+0xfb>
e2d: 4c 89 f7 mov %r14,%rdi
e30: e8 00 00 00 00 callq e35 <vxlan_netdevice_event+0x135>
e35: e9 14 ff ff ff jmpq d4e <vxlan_netdevice_event+0x4e>
e3a: e8 00 00 00 00 callq e3f <vxlan_netdevice_event+0x13f>
e3f: 90 nop
0000000000000e40 <__vxlan_sock_add>:
e40: e8 00 00 00 00 callq e45 <__vxlan_sock_add+0x5>
* and we loose the carrier due to module unload
* we also need to remove vxlan device. In other
* cases, it's not necessary and remote_ifindex
* is 0 here, so no matches.
*/
if (dst->remote_ifindex == dev->ifindex)
e45: 55 push %rbp
e46: 48 89 e5 mov %rsp,%rbp
e49: 41 57 push %r15
e4b: 41 56 push %r14
e4d: 41 55 push %r13
vxlan_dellink(vxlan->dev, &list_kill);
e4f: 41 54 push %r12
e51: 41 89 f5 mov %esi,%r13d
e54: 53 push %rbx
e55: 48 89 fb mov %rdi,%rbx
e58: 48 81 ec 88 00 00 00 sub $0x88,%rsp
}
unregister_netdevice_many(&list_kill);
e5f: 4c 8b 77 38 mov 0x38(%rdi),%r14
e63: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
e6a: 00 00
vxlan_handle_lowerdev_unregister(vn, dev);
else if (event == NETDEV_UDP_TUNNEL_PUSH_INFO)
vxlan_push_rx_ports(dev);
return NOTIFY_DONE;
}
e6c: 48 89 45 d0 mov %rax,-0x30(%rbp)
return vs;
}
static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
{
e70: 31 c0 xor %eax,%eax
e72: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # e78 <__vxlan_sock_add+0x38>
e78: 49 8b 96 88 14 00 00 mov 0x1488(%r14),%rdx
e7f: 83 e8 01 sub $0x1,%eax
e82: 80 bf 5c 01 00 00 00 cmpb $0x0,0x15c(%rdi)
e89: 0f 84 e6 01 00 00 je 1075 <__vxlan_sock_add+0x235>
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
e8f: 49 8b 96 88 14 00 00 mov 0x1488(%r14),%rdx
return vs;
}
static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
{
e96: 48 98 cltq
e98: 8b 8b 98 00 00 00 mov 0x98(%rbx),%ecx
e9e: be c0 80 40 02 mov $0x24080c0,%esi
ea3: bf 20 20 00 00 mov $0x2020,%edi
ea8: 44 0f b7 a3 3c 01 00 movzwl 0x13c(%rbx),%r12d
eaf: 00
eb0: 48 8b 44 c2 18 mov 0x18(%rdx,%rax,8),%rax
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
struct vxlan_sock *vs = NULL;
if (!vxlan->cfg.no_share) {
eb5: ba 02 00 00 00 mov $0x2,%edx
eba: 89 8d 68 ff ff ff mov %ecx,-0x98(%rbp)
ec0: 48 89 85 58 ff ff ff mov %rax,-0xa8(%rbp)
ec7: e8 00 00 00 00 callq ecc <__vxlan_sock_add+0x8c>
return -EBUSY;
}
spin_unlock(&vn->sock_lock);
}
if (!vs)
vs = vxlan_socket_create(vxlan->net, ipv6,
ecc: 48 85 c0 test %rax,%rax
#endif
static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
{
unsigned int order = get_order(size);
return kmalloc_order_trace(size, flags, order);
ecf: 49 89 c7 mov %rax,%r15
ed2: 0f 84 d1 02 00 00 je 11a9 <__vxlan_sock_add+0x369>
vxlan->cfg.dst_port, vxlan->flags);
ed8: 48 8d 40 18 lea 0x18(%rax),%rax
edc: 49 8d 97 18 20 00 00 lea 0x2018(%r15),%rdx
ee3: 48 c7 00 00 00 00 00 movq $0x0,(%rax)
return -EBUSY;
}
spin_unlock(&vn->sock_lock);
}
if (!vs)
vs = vxlan_socket_create(vxlan->net, ipv6,
eea: 48 83 c0 08 add $0x8,%rax
eee: 48 39 c2 cmp %rax,%rdx
ef1: 75 f0 jne ee3 <__vxlan_sock_add+0xa3>
ef3: 48 8d 75 a4 lea -0x5c(%rbp),%rsi
ef7: 48 8d 7d a8 lea -0x58(%rbp),%rdi
efb: 31 c0 xor %eax,%eax
struct socket *sock;
unsigned int h;
struct udp_tunnel_sock_cfg tunnel_cfg;
vs = kzalloc(sizeof(*vs), GFP_KERNEL);
if (!vs)
efd: 48 c7 45 a4 00 00 00 movq $0x0,-0x5c(%rbp)
f04: 00
f05: 48 c7 45 c8 00 00 00 movq $0x0,-0x38(%rbp)
f0c: 00
f0d: 48 89 f1 mov %rsi,%rcx
f10: 48 29 f9 sub %rdi,%rcx
return ERR_PTR(-ENOMEM);
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
f13: 83 c1 2c add $0x2c,%ecx
f16: c1 e9 03 shr $0x3,%ecx
f19: 45 84 ed test %r13b,%r13b
f1c: f3 48 ab rep stos %rax,%es:(%rdi)
vs = kzalloc(sizeof(*vs), GFP_KERNEL);
if (!vs)
return ERR_PTR(-ENOMEM);
for (h = 0; h < VNI_HASH_SIZE; ++h)
f1f: 0f 85 bc 02 00 00 jne 11e1 <__vxlan_sock_add+0x3a1>
{
struct socket *sock;
struct udp_port_cfg udp_conf;
int err;
memset(&udp_conf, 0, sizeof(udp_conf));
f25: 48 8d 85 70 ff ff ff lea -0x90(%rbp),%rax
f2c: 4c 89 f7 mov %r14,%rdi
f2f: c6 45 a4 02 movb $0x2,-0x5c(%rbp)
f33: 66 44 89 65 c8 mov %r12w,-0x38(%rbp)
f38: 48 89 c2 mov %rax,%rdx
f3b: 48 89 85 60 ff ff ff mov %rax,-0xa0(%rbp)
f42: e8 00 00 00 00 callq f47 <__vxlan_sock_add+0x107>
f47: 85 c0 test %eax,%eax
if (ipv6) {
f49: 0f 88 16 03 00 00 js 1265 <__vxlan_sock_add+0x425>
f4f: 4c 8b 9d 70 ff ff ff mov -0x90(%rbp),%r11
static inline int udp_sock_create(struct net *net,
struct udp_port_cfg *cfg,
struct socket **sockp)
{
if (cfg->family == AF_INET)
return udp_sock_create4(net, cfg, sockp);
f56: 49 81 fb 00 f0 ff ff cmp $0xfffffffffffff000,%r11
f5d: 0f 87 c6 02 00 00 ja 1229 <__vxlan_sock_add+0x3e9>
udp_conf.ipv6_v6only = 1;
} else {
udp_conf.family = AF_INET;
}
udp_conf.local_udp_port = port;
f63: 8b 85 68 ff ff ff mov -0x98(%rbp),%eax
f69: 4d 89 5f 10 mov %r11,0x10(%r15)
f6d: 66 41 c1 c4 08 rol $0x8,%r12w
f72: 41 c7 87 18 20 00 00 movl $0x1,0x2018(%r15)
f79: 01 00 00 00
/* Open UDP socket */
err = udp_sock_create(net, &udp_conf, &sock);
if (err < 0)
f7d: 4c 89 9d 50 ff ff ff mov %r11,-0xb0(%rbp)
return ERR_PTR(err);
return sock;
f84: 25 00 7d 00 00 and $0x7d00,%eax
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
sock = vxlan_create_sock(net, ipv6, port, flags);
if (IS_ERR(sock)) {
f89: 41 89 87 1c 20 00 00 mov %eax,0x201c(%r15)
f90: 48 8b 85 58 ff ff ff mov -0xa8(%rbp),%rax
return ERR_CAST(sock);
}
vs->sock = sock;
atomic_set(&vs->refcnt, 1);
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
f97: 48 05 10 08 00 00 add $0x810,%rax
/* Socket hash table head */
static inline struct hlist_head *vs_head(struct net *net, __be16 port)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
f9d: 48 89 c7 mov %rax,%rdi
fa0: 48 89 85 68 ff ff ff mov %rax,-0x98(%rbp)
static __always_inline void __write_once_size(volatile void *p, void *res, int size)
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
fa7: e8 00 00 00 00 callq fac <__vxlan_sock_add+0x16c>
fac: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # fb2 <__vxlan_sock_add+0x172>
PTR_ERR(sock));
kfree(vs);
return ERR_CAST(sock);
}
vs->sock = sock;
fb2: 49 8b 96 88 14 00 00 mov 0x1488(%r14),%rdx
atomic_set(&vs->refcnt, 1);
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
fb9: 83 e8 01 sub $0x1,%eax
fbc: 48 98 cltq
fbe: 48 8b 54 c2 18 mov 0x18(%rdx,%rax,8),%rdx
fc3: 41 0f b7 c4 movzwl %r12w,%eax
fc7: 69 c0 47 86 c8 61 imul $0x61c88647,%eax,%eax
fcd: c1 e8 18 shr $0x18,%eax
fd0: 48 83 c0 02 add $0x2,%rax
fd4: 48 8d 0c c2 lea (%rdx,%rax,8),%rcx
fd8: 48 8b 04 c2 mov (%rdx,%rax,8),%rax
fdc: 49 89 4f 08 mov %rcx,0x8(%r15)
fe0: 49 89 07 mov %rax,(%r15)
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
fe3: 48 85 c0 test %rax,%rax
fe6: 4c 89 39 mov %r15,(%rcx)
fe9: 4c 8b 9d 50 ff ff ff mov -0xb0(%rbp),%r11
ff0: 74 04 je ff6 <__vxlan_sock_add+0x1b6>
ff2: 4c 89 78 08 mov %r15,0x8(%rax)
#define hash_32 hash_32_generic
#endif
static inline u32 hash_32_generic(u32 val, unsigned int bits)
{
/* High bits are more random, so use them. */
return __hash_32(val) >> (32 - bits);
ff6: 41 8b b7 1c 20 00 00 mov 0x201c(%r15),%esi
ffd: 4c 89 df mov %r11,%rdi
/* Socket hash table head */
static inline struct hlist_head *vs_head(struct net *net, __be16 port)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
1000: 4c 89 9d 58 ff ff ff mov %r11,-0xa8(%rbp)
1007: c1 ee 0d shr $0xd,%esi
* list-traversal primitive must be guarded by rcu_read_lock().
*/
static inline void hlist_add_head_rcu(struct hlist_node *n,
struct hlist_head *h)
{
struct hlist_node *first = h->first;
100a: 83 e6 02 and $0x2,%esi
n->next = first;
n->pprev = &h->first;
100d: e8 00 00 00 00 callq 1012 <__vxlan_sock_add+0x1d2>
static inline void hlist_add_head_rcu(struct hlist_node *n,
struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
1012: 48 8b bd 68 ff ff ff mov -0x98(%rbp),%rdi
n->pprev = &h->first;
rcu_assign_pointer(hlist_first_rcu(h), n);
if (first)
1019: ff 14 25 00 00 00 00 callq *0x0
1020: 48 8b bd 60 ff ff ff mov -0xa0(%rbp),%rdi
atomic_set(&vs->refcnt, 1);
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
spin_lock(&vn->sock_lock);
hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
udp_tunnel_notify_add_rx_port(sock,
1027: 31 c0 xor %eax,%eax
1029: b9 06 00 00 00 mov $0x6,%ecx
102e: 4c 8b 9d 58 ff ff ff mov -0xa8(%rbp),%r11
1035: 48 8b 95 60 ff ff ff mov -0xa0(%rbp),%rdx
103c: f3 48 ab rep stos %rax,%es:(%rdi)
103f: 4c 89 de mov %r11,%rsi
1042: 4c 89 f7 mov %r14,%rdi
1045: 4c 89 bd 70 ff ff ff mov %r15,-0x90(%rbp)
104c: c6 85 78 ff ff ff 01 movb $0x1,-0x88(%rbp)
UDP_TUNNEL_TYPE_VXLAN_GPE :
UDP_TUNNEL_TYPE_VXLAN);
spin_unlock(&vn->sock_lock);
/* Mark socket as an encapsulation socket. */
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
1053: 48 c7 45 80 00 00 00 movq $0x0,-0x80(%rbp)
105a: 00
105b: 48 c7 45 90 00 00 00 movq $0x0,-0x70(%rbp)
1062: 00
tunnel_cfg.encap_rcv = vxlan_rcv;
tunnel_cfg.encap_destroy = NULL;
tunnel_cfg.gro_receive = vxlan_gro_receive;
tunnel_cfg.gro_complete = vxlan_gro_complete;
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
1063: 48 c7 45 98 00 00 00 movq $0x0,-0x68(%rbp)
106a: 00
106b: e8 00 00 00 00 callq 1070 <__vxlan_sock_add+0x230>
1070: e9 80 00 00 00 jmpq 10f5 <__vxlan_sock_add+0x2b5>
UDP_TUNNEL_TYPE_VXLAN);
spin_unlock(&vn->sock_lock);
/* Mark socket as an encapsulation socket. */
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
tunnel_cfg.sk_user_data = vs;
1075: 48 98 cltq
1077: 4c 8b 64 c2 18 mov 0x18(%rdx,%rax,8),%r12
tunnel_cfg.encap_type = 1;
107c: 49 81 c4 10 08 00 00 add $0x810,%r12
tunnel_cfg.encap_rcv = vxlan_rcv;
1083: 4c 89 e7 mov %r12,%rdi
1086: e8 00 00 00 00 callq 108b <__vxlan_sock_add+0x24b>
tunnel_cfg.encap_destroy = NULL;
tunnel_cfg.gro_receive = vxlan_gro_receive;
108b: 41 80 fd 01 cmp $0x1,%r13b
108f: 0f b7 93 3c 01 00 00 movzwl 0x13c(%rbx),%edx
tunnel_cfg.gro_complete = vxlan_gro_complete;
1096: 8b 8b 98 00 00 00 mov 0x98(%rbx),%ecx
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
109c: 19 f6 sbb %esi,%esi
109e: 48 8b 7b 38 mov 0x38(%rbx),%rdi
10a2: 83 e6 f8 and $0xfffffff8,%esi
10a5: 83 c6 0a add $0xa,%esi
10a8: e8 43 f0 ff ff callq f0 <vxlan_find_sock>
10ad: 48 85 c0 test %rax,%rax
10b0: 49 89 c7 mov %rax,%r15
10b3: 74 2d je 10e2 <__vxlan_sock_add+0x2a2>
10b5: 8b 88 18 20 00 00 mov 0x2018(%rax),%ecx
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
struct vxlan_sock *vs = NULL;
if (!vxlan->cfg.no_share) {
spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
10bb: 85 c9 test %ecx,%ecx
10bd: 0f 84 0d 01 00 00 je 11d0 <__vxlan_sock_add+0x390>
10c3: 48 8d b0 18 20 00 00 lea 0x2018(%rax),%rsi
10ca: 8d 51 01 lea 0x1(%rcx),%edx
10cd: 89 c8 mov %ecx,%eax
10cf: f0 41 0f b1 97 18 20 lock cmpxchg %edx,0x2018(%r15)
10d6: 00 00
10d8: 39 c1 cmp %eax,%ecx
10da: 89 c2 mov %eax,%edx
10dc: 0f 85 d3 00 00 00 jne 11b5 <__vxlan_sock_add+0x375>
10e2: 4c 89 e7 mov %r12,%rdi
10e5: ff 14 25 00 00 00 00 callq *0x0
static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
10ec: 4d 85 ff test %r15,%r15
10ef: 0f 84 78 01 00 00 je 126d <__vxlan_sock_add+0x42d>
return xadd(&v->counter, -i);
}
static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
return cmpxchg(&v->counter, old, new);
10f5: 4d 89 fb mov %r15,%r11
10f8: 49 81 fb 00 f0 ff ff cmp $0xfffffffffffff000,%r11
10ff: 0f 87 ab 00 00 00 ja 11b0 <__vxlan_sock_add+0x370>
1105: 45 84 ed test %r13b,%r13b
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
break;
old = atomic_cmpxchg((v), c, c + (a));
if (likely(old == c))
1108: 0f 84 92 00 00 00 je 11a0 <__vxlan_sock_add+0x360>
110e: 4c 89 7b 28 mov %r15,0x28(%rbx)
1112: 48 8b 43 38 mov 0x38(%rbx),%rax
1116: 44 8b 63 60 mov 0x60(%rbx),%r12d
111a: 48 8b 90 88 14 00 00 mov 0x1488(%rax),%rdx
spin_unlock(&vn->sock_lock);
return -EBUSY;
}
spin_unlock(&vn->sock_lock);
}
if (!vs)
1121: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 1127 <__vxlan_sock_add+0x2e7>
1127: 83 e8 01 sub $0x1,%eax
vs = vxlan_socket_create(vxlan->net, ipv6,
vxlan->cfg.dst_port, vxlan->flags);
if (IS_ERR(vs))
112a: 48 98 cltq
112c: 4c 8b 6c c2 18 mov 0x18(%rdx,%rax,8),%r13
1131: 49 81 c5 10 08 00 00 add $0x810,%r13
return PTR_ERR(vs);
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6)
1138: 4c 89 ef mov %r13,%rdi
113b: e8 00 00 00 00 callq 1140 <__vxlan_sock_add+0x300>
vxlan->vn6_sock = vs;
1140: 41 69 d4 47 86 c8 61 imul $0x61c88647,%r12d,%edx
}
static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
{
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
__be32 vni = vxlan->default_dst.remote_vni;
1147: c1 ea 16 shr $0x16,%edx
114a: 48 83 c2 02 add $0x2,%rdx
114e: 49 8d 0c d7 lea (%r15,%rdx,8),%rcx
1152: 49 8b 44 d7 08 mov 0x8(%r15,%rdx,8),%rax
1157: 48 8d 71 08 lea 0x8(%rcx),%rsi
115b: 48 89 03 mov %rax,(%rbx)
115e: 48 89 73 08 mov %rsi,0x8(%rbx)
1162: 48 85 c0 test %rax,%rax
1165: 48 89 59 08 mov %rbx,0x8(%rcx)
1169: 74 04 je 116f <__vxlan_sock_add+0x32f>
116b: 48 89 58 08 mov %rbx,0x8(%rax)
116f: 4c 89 ef mov %r13,%rdi
1172: ff 14 25 00 00 00 00 callq *0x0
1179: 31 c0 xor %eax,%eax
#endif
/* Virtual Network hash table head */
static inline struct hlist_head *vni_head(struct vxlan_sock *vs, __be32 vni)
{
return &vs->vni_list[hash_32((__force u32)vni, VNI_HASH_BITS)];
117b: 48 8b 75 d0 mov -0x30(%rbp),%rsi
117f: 65 48 33 34 25 28 00 xor %gs:0x28,%rsi
1186: 00 00
1188: 0f 85 d2 00 00 00 jne 1260 <__vxlan_sock_add+0x420>
struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
n->pprev = &h->first;
118e: 48 81 c4 88 00 00 00 add $0x88,%rsp
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
1195: 5b pop %rbx
1196: 41 5c pop %r12
1198: 41 5d pop %r13
rcu_assign_pointer(hlist_first_rcu(h), n);
if (first)
119a: 41 5e pop %r14
first->pprev = &n->next;
119c: 41 5f pop %r15
119e: 5d pop %rbp
119f: c3 retq
11a0: 4c 89 7b 20 mov %r15,0x20(%rbx)
11a4: e9 69 ff ff ff jmpq 1112 <__vxlan_sock_add+0x2d2>
vxlan->vn6_sock = vs;
else
#endif
vxlan->vn4_sock = vs;
vxlan_vs_add_dev(vs, vxlan);
return 0;
11a9: 49 c7 c7 f4 ff ff ff mov $0xfffffffffffffff4,%r15
}
11b0: 44 89 f8 mov %r15d,%eax
11b3: eb c6 jmp 117b <__vxlan_sock_add+0x33b>
11b5: 85 d2 test %edx,%edx
11b7: 74 17 je 11d0 <__vxlan_sock_add+0x390>
11b9: 8d 4a 01 lea 0x1(%rdx),%ecx
11bc: 89 d0 mov %edx,%eax
11be: f0 0f b1 0e lock cmpxchg %ecx,(%rsi)
11c2: 39 d0 cmp %edx,%eax
11c4: 0f 84 18 ff ff ff je 10e2 <__vxlan_sock_add+0x2a2>
11ca: 89 c2 mov %eax,%edx
11cc: 85 d2 test %edx,%edx
11ce: 75 e9 jne 11b9 <__vxlan_sock_add+0x379>
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6)
vxlan->vn6_sock = vs;
else
#endif
vxlan->vn4_sock = vs;
11d0: 4c 89 e7 mov %r12,%rdi
11d3: ff 14 25 00 00 00 00 callq *0x0
unsigned int h;
struct udp_tunnel_sock_cfg tunnel_cfg;
vs = kzalloc(sizeof(*vs), GFP_KERNEL);
if (!vs)
return ERR_PTR(-ENOMEM);
11da: b8 f0 ff ff ff mov $0xfffffff0,%eax
11df: eb 9a jmp 117b <__vxlan_sock_add+0x33b>
}
if (!vs)
vs = vxlan_socket_create(vxlan->net, ipv6,
vxlan->cfg.dst_port, vxlan->flags);
if (IS_ERR(vs))
return PTR_ERR(vs);
11e1: 8b 85 68 ff ff ff mov -0x98(%rbp),%eax
static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
11e7: 0f b6 55 cc movzbl -0x34(%rbp),%edx
break;
old = atomic_cmpxchg((v), c, c + (a));
11eb: 4c 89 f7 mov %r14,%rdi
return xadd(&v->counter, -i);
}
static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
return cmpxchg(&v->counter, old, new);
11ee: c6 45 a4 0a movb $0xa,-0x5c(%rbp)
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
break;
old = atomic_cmpxchg((v), c, c + (a));
if (likely(old == c))
11f2: 66 44 89 65 c8 mov %r12w,-0x38(%rbp)
11f7: c1 e8 08 shr $0x8,%eax
11fa: 83 f0 01 xor $0x1,%eax
static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
11fd: 83 e2 fb and $0xfffffffb,%edx
1200: 83 e0 01 and $0x1,%eax
1203: c1 e0 02 shl $0x2,%eax
1206: 09 d0 or %edx,%eax
1208: 83 c8 08 or $0x8,%eax
spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
vxlan->cfg.dst_port, vxlan->flags);
if (vs && !atomic_add_unless(&vs->refcnt, 1, 0)) {
spin_unlock(&vn->sock_lock);
return -EBUSY;
120b: 88 45 cc mov %al,-0x34(%rbp)
120e: 48 8d 85 70 ff ff ff lea -0x90(%rbp),%rax
memset(&udp_conf, 0, sizeof(udp_conf));
if (ipv6) {
udp_conf.family = AF_INET6;
udp_conf.use_udp6_rx_checksums =
1215: 48 89 c2 mov %rax,%rdx
1218: 48 89 85 60 ff ff ff mov %rax,-0xa0(%rbp)
int err;
memset(&udp_conf, 0, sizeof(udp_conf));
if (ipv6) {
udp_conf.family = AF_INET6;
121f: e8 00 00 00 00 callq 1224 <__vxlan_sock_add+0x3e4>
udp_conf.ipv6_v6only = 1;
} else {
udp_conf.family = AF_INET;
}
udp_conf.local_udp_port = port;
1224: e9 1e fd ff ff jmpq f47 <__vxlan_sock_add+0x107>
memset(&udp_conf, 0, sizeof(udp_conf));
if (ipv6) {
udp_conf.family = AF_INET6;
udp_conf.use_udp6_rx_checksums =
1229: 44 89 e6 mov %r12d,%esi
122c: 4c 89 da mov %r11,%rdx
122f: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
1236: 66 c1 c6 08 rol $0x8,%si
!(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
udp_conf.ipv6_v6only = 1;
123a: 4c 89 9d 68 ff ff ff mov %r11,-0x98(%rbp)
if (cfg->family == AF_INET6)
return udp_sock_create6(net, cfg, sockp);
1241: 0f b7 f6 movzwl %si,%esi
1244: e8 00 00 00 00 callq 1249 <__vxlan_sock_add+0x409>
1249: 4c 89 ff mov %r15,%rdi
124c: e8 00 00 00 00 callq 1251 <__vxlan_sock_add+0x411>
1251: 4c 8b 9d 68 ff ff ff mov -0x98(%rbp),%r11
1258: 4d 89 df mov %r11,%r15
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
sock = vxlan_create_sock(net, ipv6, port, flags);
if (IS_ERR(sock)) {
pr_info("Cannot bind port %d, err=%ld\n", ntohs(port),
125b: e9 98 fe ff ff jmpq 10f8 <__vxlan_sock_add+0x2b8>
1260: e8 00 00 00 00 callq 1265 <__vxlan_sock_add+0x425>
1265: 4c 63 d8 movslq %eax,%r11
1268: e9 e9 fc ff ff jmpq f56 <__vxlan_sock_add+0x116>
126d: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 1273 <__vxlan_sock_add+0x433>
1273: 4c 8b 73 38 mov 0x38(%rbx),%r14
1277: 83 e8 01 sub $0x1,%eax
PTR_ERR(sock));
kfree(vs);
127a: e9 10 fc ff ff jmpq e8f <__vxlan_sock_add+0x4f>
127f: 90 nop
0000000000001280 <vxlan_open>:
1280: e8 00 00 00 00 callq 1285 <vxlan_open+0x5>
1285: 55 push %rbp
1286: 48 89 e5 mov %rsp,%rbp
1289: 41 57 push %r15
128b: 41 56 push %r14
128d: 41 55 push %r13
128f: 41 54 push %r12
else
#endif
vxlan->vn4_sock = vs;
vxlan_vs_add_dev(vs, vxlan);
return 0;
}
1291: 4c 8d bf 40 08 00 00 lea 0x840(%rdi),%r15
1298: 53 push %rbx
1299: 48 89 fb mov %rdi,%rbx
129c: 48 83 ec 18 sub $0x18,%rsp
12a0: 48 c7 87 60 08 00 00 movq $0x0,0x860(%rdi)
12a7: 00 00 00 00
12ab: 48 c7 87 68 08 00 00 movq $0x0,0x868(%rdi)
12b2: 00 00 00 00
free_percpu(dev->tstats);
}
/* Start ageing timer and join group when device is brought up */
static int vxlan_open(struct net_device *dev)
{
12b6: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
12bd: 00 00
12bf: 48 89 45 d0 mov %rax,-0x30(%rbp)
*
* Get network device private data
*/
static inline void *netdev_priv(const struct net_device *dev)
{
return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
12c3: 31 c0 xor %eax,%eax
12c5: 8b 87 d8 08 00 00 mov 0x8d8(%rdi),%eax
12cb: 41 89 c5 mov %eax,%r13d
12ce: 41 c1 ed 0d shr $0xd,%r13d
{
bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
bool metadata = vxlan->flags & VXLAN_F_COLLECT_METADATA;
int ret = 0;
vxlan->vn4_sock = NULL;
12d2: 41 83 e5 01 and $0x1,%r13d
12d6: 83 e0 20 and $0x20,%eax
12d9: 41 89 c4 mov %eax,%r12d
#if IS_ENABLED(CONFIG_IPV6)
vxlan->vn6_sock = NULL;
12dc: 0f 85 94 00 00 00 jne 1376 <vxlan_open+0xf6>
12e2: 45 84 ed test %r13b,%r13b
12e5: 0f 85 8b 00 00 00 jne 1376 <vxlan_open+0xf6>
free_percpu(dev->tstats);
}
/* Start ageing timer and join group when device is brought up */
static int vxlan_open(struct net_device *dev)
{
12eb: 45 85 e4 test %r12d,%r12d
12ee: 0f 84 3f 01 00 00 je 1433 <vxlan_open+0x1b3>
12f4: 45 84 ed test %r13b,%r13b
return 0;
}
static int vxlan_sock_add(struct vxlan_dev *vxlan)
{
bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
12f7: 0f 85 36 01 00 00 jne 1433 <vxlan_open+0x1b3>
bool metadata = vxlan->flags & VXLAN_F_COLLECT_METADATA;
12fd: 45 31 f6 xor %r14d,%r14d
1300: 0f b7 83 80 08 00 00 movzwl 0x880(%rbx),%eax
int ret = 0;
vxlan->vn4_sock = NULL;
#if IS_ENABLED(CONFIG_IPV6)
vxlan->vn6_sock = NULL;
if (ipv6 || metadata)
1307: 66 83 f8 0a cmp $0xa,%ax
130b: 0f 84 9b 00 00 00 je 13ac <vxlan_open+0x12c>
1311: 8b 93 84 08 00 00 mov 0x884(%rbx),%edx
1317: 89 d1 mov %edx,%ecx
1319: 81 e1 f0 00 00 00 and $0xf0,%ecx
ret = __vxlan_sock_add(vxlan, true);
#endif
if (!ret && (!ipv6 || metadata))
131f: 81 f9 e0 00 00 00 cmp $0xe0,%ecx
1325: 0f 84 9c 00 00 00 je 13c7 <vxlan_open+0x147>
132b: 48 83 bb 90 09 00 00 cmpq $0x0,0x990(%rbx)
1332: 00
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
}
static inline bool vxlan_addr_multicast(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
1333: 75 25 jne 135a <vxlan_open+0xda>
1335: 48 8b 55 d0 mov -0x30(%rbp),%rdx
1339: 65 48 33 14 25 28 00 xor %gs:0x28,%rdx
1340: 00 00
return ipv6_addr_is_multicast(&ipa->sin6.sin6_addr);
else
return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
1342: 44 89 f0 mov %r14d,%eax
1345: 0f 85 3b 01 00 00 jne 1486 <vxlan_open+0x206>
ret = vxlan_sock_add(vxlan);
if (ret < 0)
return ret;
if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip)) {
134b: 48 83 c4 18 add $0x18,%rsp
134f: 5b pop %rbx
1350: 41 5c pop %r12
1352: 41 5d pop %r13
1354: 41 5e pop %r14
1356: 41 5f pop %r15
1358: 5d pop %rbp
1359: c3 retq
135a: 48 8b 35 00 00 00 00 mov 0x0(%rip),%rsi # 1361 <vxlan_open+0xe1>
vxlan_sock_release(vxlan);
return ret;
}
}
if (vxlan->cfg.age_interval)
1361: 48 8d bb e0 08 00 00 lea 0x8e0(%rbx),%rdi
mod_timer(&vxlan->age_timer, jiffies + FDB_AGE_INTERVAL);
return ret;
}
1368: 48 81 c6 c4 09 00 00 add $0x9c4,%rsi
136f: e8 00 00 00 00 callq 1374 <vxlan_open+0xf4>
1374: eb bf jmp 1335 <vxlan_open+0xb5>
1376: be 01 00 00 00 mov $0x1,%esi
137b: 4c 89 ff mov %r15,%rdi
137e: e8 bd fa ff ff callq e40 <__vxlan_sock_add>
1383: 85 c0 test %eax,%eax
1385: 41 89 c6 mov %eax,%r14d
1388: 0f 84 5d ff ff ff je 12eb <vxlan_open+0x6b>
return ret;
}
}
if (vxlan->cfg.age_interval)
mod_timer(&vxlan->age_timer, jiffies + FDB_AGE_INTERVAL);
138e: 45 85 f6 test %r14d,%r14d
1391: 0f 89 69 ff ff ff jns 1300 <vxlan_open+0x80>
1397: 48 8d b3 68 08 00 00 lea 0x868(%rbx),%rsi
139e: 48 8d bb 60 08 00 00 lea 0x860(%rbx),%rdi
13a5: e8 e6 f8 ff ff callq c90 <vxlan_sock_release.isra.44>
vxlan->vn4_sock = NULL;
#if IS_ENABLED(CONFIG_IPV6)
vxlan->vn6_sock = NULL;
if (ipv6 || metadata)
ret = __vxlan_sock_add(vxlan, true);
13aa: eb 89 jmp 1335 <vxlan_open+0xb5>
13ac: 0f b6 83 88 08 00 00 movzbl 0x888(%rbx),%eax
#endif
if (!ret && (!ipv6 || metadata))
13b3: 3d ff 00 00 00 cmp $0xff,%eax
13b8: 0f 85 6d ff ff ff jne 132b <vxlan_open+0xab>
ret = __vxlan_sock_add(vxlan, false);
if (ret < 0)
13be: 44 8b ab a4 08 00 00 mov 0x8a4(%rbx),%r13d
13c5: eb 0d jmp 13d4 <vxlan_open+0x154>
13c7: 66 83 f8 02 cmp $0x2,%ax
13cb: 44 8b ab a4 08 00 00 mov 0x8a4(%rbx),%r13d
13d2: 74 71 je 1445 <vxlan_open+0x1c5>
13d4: 48 8b 83 68 08 00 00 mov 0x868(%rbx),%rax
ret = vxlan_igmp_join(vxlan);
if (ret == -EADDRINUSE)
ret = 0;
if (ret) {
vxlan_sock_release(vxlan);
return ret;
13db: 31 f6 xor %esi,%esi
ret = vxlan_sock_add(vxlan);
if (ret < 0)
return ret;
if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip)) {
13dd: 48 8b 40 10 mov 0x10(%rax),%rax
13e1: 4c 8b 60 20 mov 0x20(%rax),%r12
13e5: 4c 89 e7 mov %r12,%rdi
13e8: e8 00 00 00 00 callq 13ed <vxlan_open+0x16d>
13ed: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 13f4 <vxlan_open+0x174>
*/
static int vxlan_igmp_join(struct vxlan_dev *vxlan)
{
struct sock *sk;
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
13f4: 4c 89 e7 mov %r12,%rdi
int ret = -EINVAL;
if (ip->sa.sa_family == AF_INET) {
13f7: 48 8d 93 88 08 00 00 lea 0x888(%rbx),%rdx
*/
static int vxlan_igmp_join(struct vxlan_dev *vxlan)
{
struct sock *sk;
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
13fe: 44 89 ee mov %r13d,%esi
1401: ff 10 callq *(%rax)
int ret = -EINVAL;
if (ip->sa.sa_family == AF_INET) {
1403: 4c 89 e7 mov %r12,%rdi
lock_sock(sk);
ret = ip_mc_join_group(sk, &mreq);
release_sock(sk);
#if IS_ENABLED(CONFIG_IPV6)
} else {
sk = vxlan->vn6_sock->sock->sk;
1406: 41 89 c6 mov %eax,%r14d
1409: e8 00 00 00 00 callq 140e <vxlan_open+0x18e>
140e: 41 83 fe 9e cmp $0xffffff9e,%r14d
1412: 74 09 je 141d <vxlan_open+0x19d>
1414: 45 85 f6 test %r14d,%r14d
void lock_sock_nested(struct sock *sk, int subclass);
static inline void lock_sock(struct sock *sk)
{
lock_sock_nested(sk, 0);
1417: 0f 85 7a ff ff ff jne 1397 <vxlan_open+0x117>
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
141d: 45 31 f6 xor %r14d,%r14d
1420: 48 83 bb 90 09 00 00 cmpq $0x0,0x990(%rbx)
1427: 00
&ip->sin6.sin6_addr);
1428: 0f 84 07 ff ff ff je 1335 <vxlan_open+0xb5>
release_sock(sk);
#if IS_ENABLED(CONFIG_IPV6)
} else {
sk = vxlan->vn6_sock->sock->sk;
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
142e: e9 27 ff ff ff jmpq 135a <vxlan_open+0xda>
&ip->sin6.sin6_addr);
release_sock(sk);
1433: 31 f6 xor %esi,%esi
1435: 4c 89 ff mov %r15,%rdi
release_sock(sk);
#if IS_ENABLED(CONFIG_IPV6)
} else {
sk = vxlan->vn6_sock->sock->sk;
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
1438: e8 03 fa ff ff callq e40 <__vxlan_sock_add>
&ip->sin6.sin6_addr);
release_sock(sk);
143d: 41 89 c6 mov %eax,%r14d
if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip)) {
ret = vxlan_igmp_join(vxlan);
if (ret == -EADDRINUSE)
ret = 0;
if (ret) {
1440: e9 49 ff ff ff jmpq 138e <vxlan_open+0x10e>
1445: 48 8b 83 60 08 00 00 mov 0x860(%rbx),%rax
144c: 31 f6 xor %esi,%esi
144e: 48 c7 45 c4 00 00 00 movq $0x0,-0x3c(%rbp)
1455: 00
vxlan_sock_release(vxlan);
return ret;
}
}
if (vxlan->cfg.age_interval)
1456: 44 89 6d cc mov %r13d,-0x34(%rbp)
145a: 89 55 c4 mov %edx,-0x3c(%rbp)
145d: 48 8b 40 10 mov 0x10(%rax),%rax
1461: 4c 8b 60 20 mov 0x20(%rax),%r12
vxlan->vn6_sock = NULL;
if (ipv6 || metadata)
ret = __vxlan_sock_add(vxlan, true);
#endif
if (!ret && (!ipv6 || metadata))
ret = __vxlan_sock_add(vxlan, false);
1465: 4c 89 e7 mov %r12,%rdi
1468: e8 00 00 00 00 callq 146d <vxlan_open+0x1ed>
146d: 48 8d 75 c4 lea -0x3c(%rbp),%rsi
1471: 4c 89 e7 mov %r12,%rdi
1474: e8 00 00 00 00 callq 1479 <vxlan_open+0x1f9>
struct ip_mreqn mreq = {
.imr_multiaddr.s_addr = ip->sin.sin_addr.s_addr,
.imr_ifindex = ifindex,
};
sk = vxlan->vn4_sock->sock->sk;
1479: 4c 89 e7 mov %r12,%rdi
147c: 41 89 c6 mov %eax,%r14d
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
int ret = -EINVAL;
if (ip->sa.sa_family == AF_INET) {
struct ip_mreqn mreq = {
147f: e8 00 00 00 00 callq 1484 <vxlan_open+0x204>
1484: eb 88 jmp 140e <vxlan_open+0x18e>
1486: e8 00 00 00 00 callq 148b <vxlan_open+0x20b>
148b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000001490 <vxlan_fill_info>:
.imr_multiaddr.s_addr = ip->sin.sin_addr.s_addr,
.imr_ifindex = ifindex,
};
sk = vxlan->vn4_sock->sock->sk;
1490: e8 00 00 00 00 callq 1495 <vxlan_fill_info+0x5>
1495: 55 push %rbp
1496: ba 04 00 00 00 mov $0x4,%edx
149b: 48 89 e5 mov %rsp,%rbp
lock_sock(sk);
ret = ip_mc_join_group(sk, &mreq);
149e: 41 55 push %r13
14a0: 41 54 push %r12
14a2: 53 push %rbx
14a3: 48 8d 4d c0 lea -0x40(%rbp),%rcx
14a7: 48 89 f3 mov %rsi,%rbx
release_sock(sk);
14aa: 49 89 fc mov %rdi,%r12
.imr_ifindex = ifindex,
};
sk = vxlan->vn4_sock->sock->sk;
lock_sock(sk);
ret = ip_mc_join_group(sk, &mreq);
14ad: 48 83 ec 38 sub $0x38,%rsp
release_sock(sk);
14b1: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
14b8: 00 00
if (vxlan->cfg.age_interval)
mod_timer(&vxlan->age_timer, jiffies + FDB_AGE_INTERVAL);
return ret;
}
14ba: 48 89 45 e0 mov %rax,-0x20(%rbp)
14be: 31 c0 xor %eax,%eax
nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_RX */
0;
}
static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
14c0: 0f b7 86 7e 09 00 00 movzwl 0x97e(%rsi),%eax
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
{
return nla_put(skb, attrtype, sizeof(u32), &value);
14c7: 66 c1 c0 08 rol $0x8,%ax
14cb: 66 89 45 dc mov %ax,-0x24(%rbp)
14cf: 0f b7 86 80 09 00 00 movzwl 0x980(%rsi),%eax
14d6: 66 c1 c0 08 rol $0x8,%ax
14da: 66 89 45 de mov %ax,-0x22(%rbp)
14de: 8b 86 a0 08 00 00 mov 0x8a0(%rsi),%eax
14e4: be 01 00 00 00 mov $0x1,%esi
14e9: 0f c8 bswap %eax
14eb: 89 45 c0 mov %eax,-0x40(%rbp)
14ee: e8 00 00 00 00 callq 14f3 <vxlan_fill_info+0x63>
const struct vxlan_dev *vxlan = netdev_priv(dev);
const struct vxlan_rdst *dst = &vxlan->default_dst;
struct ifla_vxlan_port_range ports = {
.low = htons(vxlan->cfg.port_min),
14f3: 85 c0 test %eax,%eax
14f5: 0f 85 9b 03 00 00 jne 1896 <vxlan_fill_info+0x406>
static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
const struct vxlan_dev *vxlan = netdev_priv(dev);
const struct vxlan_rdst *dst = &vxlan->default_dst;
struct ifla_vxlan_port_range ports = {
14fb: 0f b7 83 80 08 00 00 movzwl 0x880(%rbx),%eax
.low = htons(vxlan->cfg.port_min),
.high = htons(vxlan->cfg.port_max),
1502: 66 83 f8 0a cmp $0xa,%ax
1506: 0f 84 2d 04 00 00 je 1939 <vxlan_fill_info+0x4a9>
static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
const struct vxlan_dev *vxlan = netdev_priv(dev);
const struct vxlan_rdst *dst = &vxlan->default_dst;
struct ifla_vxlan_port_range ports = {
150c: 8b 93 84 08 00 00 mov 0x884(%rbx),%edx
.low = htons(vxlan->cfg.port_min),
.high = htons(vxlan->cfg.port_max),
};
if (nla_put_u32(skb, IFLA_VXLAN_ID, be32_to_cpu(dst->remote_vni)))
1512: 85 d2 test %edx,%edx
1514: 0f 85 a3 03 00 00 jne 18bd <vxlan_fill_info+0x42d>
151a: 8b 83 a4 08 00 00 mov 0x8a4(%rbx),%eax
1520: 85 c0 test %eax,%eax
1522: 0f 85 ca 03 00 00 jne 18f2 <vxlan_fill_info+0x462>
1528: 0f b7 83 54 09 00 00 movzwl 0x954(%rbx),%eax
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
152f: 66 83 f8 0a cmp $0xa,%ax
1533: 0f 84 e7 03 00 00 je 1920 <vxlan_fill_info+0x490>
1539: 8b 93 58 09 00 00 mov 0x958(%rbx),%edx
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
153f: 85 d2 test %edx,%edx
1541: 74 2b je 156e <vxlan_fill_info+0xde>
};
if (nla_put_u32(skb, IFLA_VXLAN_ID, be32_to_cpu(dst->remote_vni)))
goto nla_put_failure;
if (!vxlan_addr_any(&dst->remote_ip)) {
1543: 66 83 f8 02 cmp $0x2,%ax
1547: 0f 84 05 04 00 00 je 1952 <vxlan_fill_info+0x4c2>
goto nla_put_failure;
#endif
}
}
if (dst->remote_ifindex && nla_put_u32(skb, IFLA_VXLAN_LINK, dst->remote_ifindex))
154d: 48 8d 8b 5c 09 00 00 lea 0x95c(%rbx),%rcx
1554: ba 10 00 00 00 mov $0x10,%edx
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
1559: be 11 00 00 00 mov $0x11,%esi
155e: 4c 89 e7 mov %r12,%rdi
1561: e8 00 00 00 00 callq 1566 <vxlan_fill_info+0xd6>
1566: 85 c0 test %eax,%eax
1568: 0f 85 28 03 00 00 jne 1896 <vxlan_fill_info+0x406>
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
156e: 0f b6 83 83 09 00 00 movzbl 0x983(%rbx),%eax
if (dst->remote_ifindex && nla_put_u32(skb, IFLA_VXLAN_LINK, dst->remote_ifindex))
goto nla_put_failure;
if (!vxlan_addr_any(&vxlan->cfg.saddr)) {
if (vxlan->cfg.saddr.sa.sa_family == AF_INET) {
1575: 48 8d 4d b1 lea -0x4f(%rbp),%rcx
1579: ba 01 00 00 00 mov $0x1,%edx
if (nla_put_in_addr(skb, IFLA_VXLAN_LOCAL,
vxlan->cfg.saddr.sin.sin_addr.s_addr))
goto nla_put_failure;
#if IS_ENABLED(CONFIG_IPV6)
} else {
if (nla_put_in6_addr(skb, IFLA_VXLAN_LOCAL6,
157e: be 05 00 00 00 mov $0x5,%esi
1583: 4c 89 e7 mov %r12,%rdi
* @addr: IPv6 address
*/
static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
const struct in6_addr *addr)
{
return nla_put(skb, attrtype, sizeof(*addr), addr);
1586: 88 45 b1 mov %al,-0x4f(%rbp)
1589: e8 00 00 00 00 callq 158e <vxlan_fill_info+0xfe>
158e: 85 c0 test %eax,%eax
1590: 0f 85 00 03 00 00 jne 1896 <vxlan_fill_info+0x406>
1596: 0f b6 83 82 09 00 00 movzbl 0x982(%rbx),%eax
159d: 48 8d 4d b2 lea -0x4e(%rbp),%rcx
15a1: ba 01 00 00 00 mov $0x1,%edx
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
{
return nla_put(skb, attrtype, sizeof(u8), &value);
15a6: be 06 00 00 00 mov $0x6,%esi
15ab: 4c 89 e7 mov %r12,%rdi
15ae: 88 45 b2 mov %al,-0x4e(%rbp)
15b1: e8 00 00 00 00 callq 15b6 <vxlan_fill_info+0x126>
15b6: 85 c0 test %eax,%eax
15b8: 0f 85 d8 02 00 00 jne 1896 <vxlan_fill_info+0x406>
goto nla_put_failure;
#endif
}
}
if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->cfg.ttl) ||
15be: 8b 83 84 09 00 00 mov 0x984(%rbx),%eax
15c4: 48 8d 4d d0 lea -0x30(%rbp),%rcx
15c8: ba 04 00 00 00 mov $0x4,%edx
15cd: be 1a 00 00 00 mov $0x1a,%esi
15d2: 4c 89 e7 mov %r12,%rdi
15d5: 89 45 d0 mov %eax,-0x30(%rbp)
15d8: e8 00 00 00 00 callq 15dd <vxlan_fill_info+0x14d>
15dd: 85 c0 test %eax,%eax
15df: 0f 85 b1 02 00 00 jne 1896 <vxlan_fill_info+0x406>
15e5: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
15eb: 48 8d 4d b3 lea -0x4d(%rbp),%rcx
15ef: ba 01 00 00 00 mov $0x1,%edx
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
{
return nla_put(skb, attrtype, sizeof(__be32), &value);
15f4: be 07 00 00 00 mov $0x7,%esi
15f9: 4c 89 e7 mov %r12,%rdi
15fc: 88 45 b3 mov %al,-0x4d(%rbp)
15ff: 80 65 b3 01 andb $0x1,-0x4d(%rbp)
1603: e8 00 00 00 00 callq 1608 <vxlan_fill_info+0x178>
1608: 85 c0 test %eax,%eax
160a: 0f 85 86 02 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_TOS, vxlan->cfg.tos) ||
1610: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
1616: 48 8d 4d b4 lea -0x4c(%rbp),%rcx
161a: ba 01 00 00 00 mov $0x1,%edx
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
{
return nla_put(skb, attrtype, sizeof(u8), &value);
161f: be 0b 00 00 00 mov $0xb,%esi
1624: 4c 89 e7 mov %r12,%rdi
1627: d1 e8 shr %eax
1629: 83 e0 01 and $0x1,%eax
162c: 88 45 b4 mov %al,-0x4c(%rbp)
162f: e8 00 00 00 00 callq 1634 <vxlan_fill_info+0x1a4>
1634: 85 c0 test %eax,%eax
1636: 0f 85 5a 02 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_be32(skb, IFLA_VXLAN_LABEL, vxlan->cfg.label) ||
163c: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
1642: 48 8d 4d b5 lea -0x4b(%rbp),%rcx
1646: ba 01 00 00 00 mov $0x1,%edx
164b: be 0c 00 00 00 mov $0xc,%esi
1650: 4c 89 e7 mov %r12,%rdi
1653: c1 e8 02 shr $0x2,%eax
1656: 83 e0 01 and $0x1,%eax
1659: 88 45 b5 mov %al,-0x4b(%rbp)
165c: e8 00 00 00 00 callq 1661 <vxlan_fill_info+0x1d1>
1661: 85 c0 test %eax,%eax
1663: 0f 85 2d 02 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_LEARNING,
!!(vxlan->flags & VXLAN_F_LEARN)) ||
1669: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
166f: 48 8d 4d b6 lea -0x4a(%rbp),%rcx
1673: ba 01 00 00 00 mov $0x1,%edx
1678: be 0d 00 00 00 mov $0xd,%esi
167d: 4c 89 e7 mov %r12,%rdi
1680: c1 e8 03 shr $0x3,%eax
1683: 83 e0 01 and $0x1,%eax
1686: 88 45 b6 mov %al,-0x4a(%rbp)
1689: e8 00 00 00 00 callq 168e <vxlan_fill_info+0x1fe>
168e: 85 c0 test %eax,%eax
1690: 0f 85 00 02 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_PROXY,
!!(vxlan->flags & VXLAN_F_PROXY)) ||
1696: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
169c: 48 8d 4d b7 lea -0x49(%rbp),%rcx
16a0: ba 01 00 00 00 mov $0x1,%edx
16a5: be 0e 00 00 00 mov $0xe,%esi
16aa: 4c 89 e7 mov %r12,%rdi
16ad: c1 e8 04 shr $0x4,%eax
16b0: 83 e0 01 and $0x1,%eax
16b3: 88 45 b7 mov %al,-0x49(%rbp)
16b6: e8 00 00 00 00 callq 16bb <vxlan_fill_info+0x22b>
16bb: 85 c0 test %eax,%eax
16bd: 0f 85 d3 01 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_RSC, !!(vxlan->flags & VXLAN_F_RSC)) ||
16c3: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
16c9: 48 8d 4d b8 lea -0x48(%rbp),%rcx
16cd: ba 01 00 00 00 mov $0x1,%edx
16d2: be 19 00 00 00 mov $0x19,%esi
16d7: 4c 89 e7 mov %r12,%rdi
16da: c1 e8 0d shr $0xd,%eax
16dd: 83 e0 01 and $0x1,%eax
16e0: 88 45 b8 mov %al,-0x48(%rbp)
16e3: e8 00 00 00 00 callq 16e8 <vxlan_fill_info+0x258>
16e8: 85 c0 test %eax,%eax
16ea: 0f 85 a6 01 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_L2MISS,
!!(vxlan->flags & VXLAN_F_L2MISS)) ||
16f0: 48 8b 83 90 09 00 00 mov 0x990(%rbx),%rax
16f7: 48 8d 4d d4 lea -0x2c(%rbp),%rcx
16fb: ba 04 00 00 00 mov $0x4,%edx
1700: be 08 00 00 00 mov $0x8,%esi
1705: 4c 89 e7 mov %r12,%rdi
1708: 89 45 d4 mov %eax,-0x2c(%rbp)
170b: e8 00 00 00 00 callq 1710 <vxlan_fill_info+0x280>
1710: 85 c0 test %eax,%eax
1712: 0f 85 7e 01 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_L3MISS,
!!(vxlan->flags & VXLAN_F_L3MISS)) ||
1718: 8b 83 98 09 00 00 mov 0x998(%rbx),%eax
171e: 48 8d 4d d8 lea -0x28(%rbp),%rcx
1722: ba 04 00 00 00 mov $0x4,%edx
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
{
return nla_put(skb, attrtype, sizeof(u32), &value);
1727: be 09 00 00 00 mov $0x9,%esi
172c: 4c 89 e7 mov %r12,%rdi
172f: 89 45 d8 mov %eax,-0x28(%rbp)
1732: e8 00 00 00 00 callq 1737 <vxlan_fill_info+0x2a7>
1737: 85 c0 test %eax,%eax
1739: 0f 85 57 01 00 00 jne 1896 <vxlan_fill_info+0x406>
173f: 0f b7 83 7c 09 00 00 movzwl 0x97c(%rbx),%eax
nla_put_u8(skb, IFLA_VXLAN_COLLECT_METADATA,
!!(vxlan->flags & VXLAN_F_COLLECT_METADATA)) ||
1746: 48 8d 4d be lea -0x42(%rbp),%rcx
174a: ba 02 00 00 00 mov $0x2,%edx
174f: be 0f 00 00 00 mov $0xf,%esi
1754: 4c 89 e7 mov %r12,%rdi
1757: 66 89 45 be mov %ax,-0x42(%rbp)
175b: e8 00 00 00 00 callq 1760 <vxlan_fill_info+0x2d0>
1760: 85 c0 test %eax,%eax
1762: 0f 85 2e 01 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u32(skb, IFLA_VXLAN_AGEING, vxlan->cfg.age_interval) ||
1768: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
176e: 48 8d 4d b9 lea -0x47(%rbp),%rcx
1772: ba 01 00 00 00 mov $0x1,%edx
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
{
return nla_put(skb, attrtype, sizeof(__be16), &value);
1777: be 12 00 00 00 mov $0x12,%esi
177c: 4c 89 e7 mov %r12,%rdi
177f: c1 e8 06 shr $0x6,%eax
1782: 83 f0 01 xor $0x1,%eax
1785: 83 e0 01 and $0x1,%eax
1788: 88 45 b9 mov %al,-0x47(%rbp)
178b: e8 00 00 00 00 callq 1790 <vxlan_fill_info+0x300>
nla_put_u32(skb, IFLA_VXLAN_LIMIT, vxlan->cfg.addrmax) ||
1790: 85 c0 test %eax,%eax
1792: 0f 85 fe 00 00 00 jne 1896 <vxlan_fill_info+0x406>
1798: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
{
return nla_put(skb, attrtype, sizeof(u8), &value);
179e: 48 8d 4d ba lea -0x46(%rbp),%rcx
17a2: ba 01 00 00 00 mov $0x1,%edx
17a7: be 13 00 00 00 mov $0x13,%esi
17ac: 4c 89 e7 mov %r12,%rdi
17af: c1 e8 07 shr $0x7,%eax
17b2: 83 e0 01 and $0x1,%eax
17b5: 88 45 ba mov %al,-0x46(%rbp)
17b8: e8 00 00 00 00 callq 17bd <vxlan_fill_info+0x32d>
17bd: 85 c0 test %eax,%eax
17bf: 0f 85 d1 00 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_be16(skb, IFLA_VXLAN_PORT, vxlan->cfg.dst_port) ||
17c5: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
17cb: 48 8d 4d bb lea -0x45(%rbp),%rcx
17cf: ba 01 00 00 00 mov $0x1,%edx
17d4: be 14 00 00 00 mov $0x14,%esi
17d9: 4c 89 e7 mov %r12,%rdi
17dc: c1 e8 08 shr $0x8,%eax
17df: 83 e0 01 and $0x1,%eax
17e2: 88 45 bb mov %al,-0x45(%rbp)
17e5: e8 00 00 00 00 callq 17ea <vxlan_fill_info+0x35a>
17ea: 85 c0 test %eax,%eax
17ec: 0f 85 a4 00 00 00 jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_UDP_CSUM,
!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM_TX)) ||
17f2: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
17f8: 48 8d 4d bc lea -0x44(%rbp),%rcx
17fc: ba 01 00 00 00 mov $0x1,%edx
1801: be 15 00 00 00 mov $0x15,%esi
1806: 4c 89 e7 mov %r12,%rdi
1809: c1 e8 09 shr $0x9,%eax
180c: 83 e0 01 and $0x1,%eax
180f: 88 45 bc mov %al,-0x44(%rbp)
1812: e8 00 00 00 00 callq 1817 <vxlan_fill_info+0x387>
1817: 85 c0 test %eax,%eax
1819: 75 7b jne 1896 <vxlan_fill_info+0x406>
nla_put_u8(skb, IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
!!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM6_TX)) ||
181b: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
1821: 48 8d 4d bd lea -0x43(%rbp),%rcx
1825: ba 01 00 00 00 mov $0x1,%edx
182a: be 16 00 00 00 mov $0x16,%esi
182f: 4c 89 e7 mov %r12,%rdi
1832: c1 e8 0a shr $0xa,%eax
1835: 83 e0 01 and $0x1,%eax
1838: 88 45 bd mov %al,-0x43(%rbp)
183b: e8 00 00 00 00 callq 1840 <vxlan_fill_info+0x3b0>
1840: 85 c0 test %eax,%eax
1842: 75 52 jne 1896 <vxlan_fill_info+0x406>
1844: 48 8d 4d dc lea -0x24(%rbp),%rcx
nla_put_u8(skb, IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
!!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM6_RX)) ||
1848: ba 04 00 00 00 mov $0x4,%edx
184d: be 0a 00 00 00 mov $0xa,%esi
1852: 4c 89 e7 mov %r12,%rdi
1855: e8 00 00 00 00 callq 185a <vxlan_fill_info+0x3ca>
185a: 85 c0 test %eax,%eax
185c: 41 89 c5 mov %eax,%r13d
185f: 75 35 jne 1896 <vxlan_fill_info+0x406>
1861: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
1867: f6 c4 08 test $0x8,%ah
186a: 0f 85 2e 01 00 00 jne 199e <vxlan_fill_info+0x50e>
nla_put_u8(skb, IFLA_VXLAN_REMCSUM_TX,
!!(vxlan->flags & VXLAN_F_REMCSUM_TX)) ||
1870: f6 c4 40 test $0x40,%ah
1873: 0f 85 49 01 00 00 jne 19c2 <vxlan_fill_info+0x532>
nla_put_u8(skb, IFLA_VXLAN_REMCSUM_RX,
!!(vxlan->flags & VXLAN_F_REMCSUM_RX)))
goto nla_put_failure;
if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports))
1879: f6 c4 10 test $0x10,%ah
187c: 74 1e je 189c <vxlan_fill_info+0x40c>
187e: 31 c9 xor %ecx,%ecx
1880: 31 d2 xor %edx,%edx
1882: be 18 00 00 00 mov $0x18,%esi
1887: 4c 89 e7 mov %r12,%rdi
188a: e8 00 00 00 00 callq 188f <vxlan_fill_info+0x3ff>
188f: 85 c0 test %eax,%eax
goto nla_put_failure;
if (vxlan->flags & VXLAN_F_GBP &&
1891: 41 89 c5 mov %eax,%r13d
1894: 74 06 je 189c <vxlan_fill_info+0x40c>
1896: 41 bd a6 ff ff ff mov $0xffffffa6,%r13d
189c: 48 8b 75 e0 mov -0x20(%rbp),%rsi
nla_put_flag(skb, IFLA_VXLAN_GBP))
goto nla_put_failure;
if (vxlan->flags & VXLAN_F_GPE &&
18a0: 65 48 33 34 25 28 00 xor %gs:0x28,%rsi
18a7: 00 00
nla_put_flag(skb, IFLA_VXLAN_GPE))
goto nla_put_failure;
if (vxlan->flags & VXLAN_F_REMCSUM_NOPARTIAL &&
18a9: 44 89 e8 mov %r13d,%eax
18ac: 0f 85 34 01 00 00 jne 19e6 <vxlan_fill_info+0x556>
* @skb: socket buffer to add attribute to
* @attrtype: attribute type
*/
static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
{
return nla_put(skb, attrtype, 0, NULL);
18b2: 48 83 c4 38 add $0x38,%rsp
18b6: 5b pop %rbx
18b7: 41 5c pop %r12
18b9: 41 5d pop %r13
18bb: 5d pop %rbp
18bc: c3 retq
18bd: 66 83 f8 02 cmp $0x2,%ax
18c1: 0f 84 b1 00 00 00 je 1978 <vxlan_fill_info+0x4e8>
goto nla_put_failure;
return 0;
nla_put_failure:
return -EMSGSIZE;
18c7: 48 8d 8b 88 08 00 00 lea 0x888(%rbx),%rcx
}
18ce: ba 10 00 00 00 mov $0x10,%edx
18d3: be 10 00 00 00 mov $0x10,%esi
18d8: 4c 89 e7 mov %r12,%rdi
18db: e8 00 00 00 00 callq 18e0 <vxlan_fill_info+0x450>
18e0: 85 c0 test %eax,%eax
18e2: 75 b2 jne 1896 <vxlan_fill_info+0x406>
18e4: 8b 83 a4 08 00 00 mov 0x8a4(%rbx),%eax
18ea: 85 c0 test %eax,%eax
18ec: 0f 84 36 fc ff ff je 1528 <vxlan_fill_info+0x98>
if (nla_put_u32(skb, IFLA_VXLAN_ID, be32_to_cpu(dst->remote_vni)))
goto nla_put_failure;
if (!vxlan_addr_any(&dst->remote_ip)) {
if (dst->remote_ip.sa.sa_family == AF_INET) {
18f2: 48 8d 4d c8 lea -0x38(%rbp),%rcx
18f6: ba 04 00 00 00 mov $0x4,%edx
if (nla_put_in_addr(skb, IFLA_VXLAN_GROUP,
dst->remote_ip.sin.sin_addr.s_addr))
goto nla_put_failure;
#if IS_ENABLED(CONFIG_IPV6)
} else {
if (nla_put_in6_addr(skb, IFLA_VXLAN_GROUP6,
18fb: be 03 00 00 00 mov $0x3,%esi
* @addr: IPv6 address
*/
static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
const struct in6_addr *addr)
{
return nla_put(skb, attrtype, sizeof(*addr), addr);
1900: 4c 89 e7 mov %r12,%rdi
1903: 89 45 c8 mov %eax,-0x38(%rbp)
1906: e8 00 00 00 00 callq 190b <vxlan_fill_info+0x47b>
190b: 85 c0 test %eax,%eax
190d: 75 87 jne 1896 <vxlan_fill_info+0x406>
190f: 0f b7 83 54 09 00 00 movzwl 0x954(%rbx),%eax
goto nla_put_failure;
#endif
}
}
if (dst->remote_ifindex && nla_put_u32(skb, IFLA_VXLAN_LINK, dst->remote_ifindex))
1916: 66 83 f8 0a cmp $0xa,%ax
191a: 0f 85 19 fc ff ff jne 1539 <vxlan_fill_info+0xa9>
1920: 48 8b 83 5c 09 00 00 mov 0x95c(%rbx),%rax
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
{
return nla_put(skb, attrtype, sizeof(u32), &value);
1927: 48 0b 83 64 09 00 00 or 0x964(%rbx),%rax
192e: 0f 85 19 fc ff ff jne 154d <vxlan_fill_info+0xbd>
1934: e9 35 fc ff ff jmpq 156e <vxlan_fill_info+0xde>
1939: 48 8b 83 88 08 00 00 mov 0x888(%rbx),%rax
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
1940: 48 0b 83 90 08 00 00 or 0x890(%rbx),%rax
1947: 0f 85 7a ff ff ff jne 18c7 <vxlan_fill_info+0x437>
194d: e9 c8 fb ff ff jmpq 151a <vxlan_fill_info+0x8a>
}
if (dst->remote_ifindex && nla_put_u32(skb, IFLA_VXLAN_LINK, dst->remote_ifindex))
goto nla_put_failure;
if (!vxlan_addr_any(&vxlan->cfg.saddr)) {
1952: 48 8d 4d cc lea -0x34(%rbp),%rcx
1956: 89 55 cc mov %edx,-0x34(%rbp)
1959: be 04 00 00 00 mov $0x4,%esi
195e: ba 04 00 00 00 mov $0x4,%edx
1963: 4c 89 e7 mov %r12,%rdi
1966: e8 00 00 00 00 callq 196b <vxlan_fill_info+0x4db>
};
if (nla_put_u32(skb, IFLA_VXLAN_ID, be32_to_cpu(dst->remote_vni)))
goto nla_put_failure;
if (!vxlan_addr_any(&dst->remote_ip)) {
196b: 85 c0 test %eax,%eax
196d: 0f 84 fb fb ff ff je 156e <vxlan_fill_info+0xde>
1973: e9 1e ff ff ff jmpq 1896 <vxlan_fill_info+0x406>
1978: 48 8d 4d c4 lea -0x3c(%rbp),%rcx
197c: 89 55 c4 mov %edx,-0x3c(%rbp)
197f: be 02 00 00 00 mov $0x2,%esi
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
{
return nla_put(skb, attrtype, sizeof(__be32), &value);
1984: ba 04 00 00 00 mov $0x4,%edx
1989: 4c 89 e7 mov %r12,%rdi
198c: e8 00 00 00 00 callq 1991 <vxlan_fill_info+0x501>
1991: 85 c0 test %eax,%eax
1993: 0f 84 81 fb ff ff je 151a <vxlan_fill_info+0x8a>
1999: e9 f8 fe ff ff jmpq 1896 <vxlan_fill_info+0x406>
if (dst->remote_ifindex && nla_put_u32(skb, IFLA_VXLAN_LINK, dst->remote_ifindex))
goto nla_put_failure;
if (!vxlan_addr_any(&vxlan->cfg.saddr)) {
if (vxlan->cfg.saddr.sa.sa_family == AF_INET) {
if (nla_put_in_addr(skb, IFLA_VXLAN_LOCAL,
199e: 31 c9 xor %ecx,%ecx
19a0: 31 d2 xor %edx,%edx
19a2: be 17 00 00 00 mov $0x17,%esi
19a7: 4c 89 e7 mov %r12,%rdi
19aa: e8 00 00 00 00 callq 19af <vxlan_fill_info+0x51f>
19af: 85 c0 test %eax,%eax
19b1: 0f 85 df fe ff ff jne 1896 <vxlan_fill_info+0x406>
19b7: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
19bd: e9 ae fe ff ff jmpq 1870 <vxlan_fill_info+0x3e0>
if (nla_put_u32(skb, IFLA_VXLAN_ID, be32_to_cpu(dst->remote_vni)))
goto nla_put_failure;
if (!vxlan_addr_any(&dst->remote_ip)) {
if (dst->remote_ip.sa.sa_family == AF_INET) {
if (nla_put_in_addr(skb, IFLA_VXLAN_GROUP,
19c2: 31 c9 xor %ecx,%ecx
19c4: 31 d2 xor %edx,%edx
19c6: be 1b 00 00 00 mov $0x1b,%esi
19cb: 4c 89 e7 mov %r12,%rdi
* @skb: socket buffer to add attribute to
* @attrtype: attribute type
*/
static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
{
return nla_put(skb, attrtype, 0, NULL);
19ce: e8 00 00 00 00 callq 19d3 <vxlan_fill_info+0x543>
19d3: 85 c0 test %eax,%eax
19d5: 0f 85 bb fe ff ff jne 1896 <vxlan_fill_info+0x406>
19db: 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%eax
goto nla_put_failure;
if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports))
goto nla_put_failure;
if (vxlan->flags & VXLAN_F_GBP &&
19e1: e9 93 fe ff ff jmpq 1879 <vxlan_fill_info+0x3e9>
19e6: e8 00 00 00 00 callq 19eb <vxlan_fill_info+0x55b>
19eb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
00000000000019f0 <vxlan_fdb_info>:
19f0: e8 00 00 00 00 callq 19f5 <vxlan_fdb_info+0x5>
19f5: 55 push %rbp
19f6: 48 89 e5 mov %rsp,%rbp
19f9: 41 57 push %r15
19fb: 41 56 push %r14
19fd: 41 55 push %r13
19ff: 41 54 push %r12
1a01: 53 push %rbx
1a02: 48 83 ec 40 sub $0x40,%rsp
nla_put_flag(skb, IFLA_VXLAN_GBP))
goto nla_put_failure;
if (vxlan->flags & VXLAN_F_GPE &&
1a06: 44 8b 97 84 00 00 00 mov 0x84(%rdi),%r10d
1a0d: 4c 8b 75 18 mov 0x18(%rbp),%r14
1a11: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
1a18: 00 00
return 0;
nla_put_failure:
return -EMSGSIZE;
}
1a1a: 48 89 45 d0 mov %rax,-0x30(%rbp)
1a1e: 31 c0 xor %eax,%eax
/* Fill in neighbour message in skbuff. */
static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
const struct vxlan_fdb *fdb,
u32 portid, u32 seq, int type, unsigned int flags,
const struct vxlan_rdst *rdst)
{
1a20: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 1a27 <vxlan_fdb_info+0x37>
1a27: 45 85 d2 test %r10d,%r10d
1a2a: 48 89 45 a0 mov %rax,-0x60(%rbp)
1a2e: 0f 85 34 02 00 00 jne 1c68 <vxlan_fdb_info+0x278>
1a34: 8b 87 cc 00 00 00 mov 0xcc(%rdi),%eax
*
* Return the number of bytes of free space at the tail of an sk_buff
*/
static inline int skb_tailroom(const struct sk_buff *skb)
{
return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail;
1a3a: 2b 87 c8 00 00 00 sub 0xc8(%rdi),%eax
1a40: 49 89 fc mov %rdi,%r12
1a43: 83 f8 1b cmp $0x1b,%eax
1a46: 0f 8e 1c 02 00 00 jle 1c68 <vxlan_fdb_info+0x278>
1a4c: 45 89 cb mov %r9d,%r11d
1a4f: 44 8b 4d 10 mov 0x10(%rbp),%r9d
unsigned long now = jiffies;
1a53: 49 89 f7 mov %rsi,%r15
1a56: 49 89 d5 mov %rdx,%r13
1a59: 89 ce mov %ecx,%esi
1a5b: 44 89 c2 mov %r8d,%edx
1a5e: 44 89 d9 mov %r11d,%ecx
1a61: 41 b8 0c 00 00 00 mov $0xc,%r8d
* the message header and payload.
*/
static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
int type, int payload, int flags)
{
if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
1a67: 44 89 5d 9c mov %r11d,-0x64(%rbp)
1a6b: e8 00 00 00 00 callq 1a70 <vxlan_fdb_info+0x80>
1a70: 48 85 c0 test %rax,%rax
1a73: 48 89 c3 mov %rax,%rbx
1a76: 0f 84 ec 01 00 00 je 1c68 <vxlan_fdb_info+0x278>
1a7c: 44 8b 5d 9c mov -0x64(%rbp),%r11d
return NULL;
return __nlmsg_put(skb, portid, seq, type, payload, flags);
1a80: 48 c7 40 10 00 00 00 movq $0x0,0x10(%rax)
1a87: 00
1a88: c7 40 18 00 00 00 00 movl $0x0,0x18(%rax)
1a8f: 41 83 fb 1e cmp $0x1e,%r11d
1a93: 0f 84 22 02 00 00 je 1cbb <vxlan_fdb_info+0x2cb>
1a99: c6 40 10 07 movb $0x7,0x10(%rax)
1a9d: 41 b9 01 00 00 00 mov $0x1,%r9d
1aa3: 41 b8 01 00 00 00 mov $0x1,%r8d
struct nlmsghdr *nlh;
struct ndmsg *ndm;
bool send_ip, send_eth;
nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
if (nlh == NULL)
1aa9: 41 0f b7 45 46 movzwl 0x46(%r13),%eax
ndm = nlmsg_data(nlh);
memset(ndm, 0, sizeof(*ndm));
send_eth = send_ip = true;
if (type == RTM_GETNEIGH) {
1aae: 66 89 43 18 mov %ax,0x18(%rbx)
nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
if (nlh == NULL)
return -EMSGSIZE;
ndm = nlmsg_data(nlh);
memset(ndm, 0, sizeof(*ndm));
1ab2: 49 8b 47 30 mov 0x30(%r15),%rax
1ab6: 8b 80 28 01 00 00 mov 0x128(%rax),%eax
1abc: 89 43 14 mov %eax,0x14(%rbx)
send_eth = send_ip = true;
if (type == RTM_GETNEIGH) {
1abf: 41 0f b6 45 48 movzbl 0x48(%r13),%eax
1ac4: c6 43 1b 01 movb $0x1,0x1b(%rbx)
1ac8: 88 43 1a mov %al,0x1a(%rbx)
ndm->ndm_family = AF_INET;
send_ip = !vxlan_addr_any(&rdst->remote_ip);
send_eth = !is_zero_ether_addr(fdb->eth_addr);
} else
ndm->ndm_family = AF_BRIDGE;
1acb: 49 8b 47 30 mov 0x30(%r15),%rax
return -EMSGSIZE;
ndm = nlmsg_data(nlh);
memset(ndm, 0, sizeof(*ndm));
send_eth = send_ip = true;
1acf: 49 8b 77 38 mov 0x38(%r15),%rsi
1ad3: 48 8b b8 80 04 00 00 mov 0x480(%rax),%rdi
ndm->ndm_family = AF_INET;
send_ip = !vxlan_addr_any(&rdst->remote_ip);
send_eth = !is_zero_ether_addr(fdb->eth_addr);
} else
ndm->ndm_family = AF_BRIDGE;
ndm->ndm_state = fdb->state;
1ada: 48 39 fe cmp %rdi,%rsi
1add: 74 38 je 1b17 <vxlan_fdb_info+0x127>
1adf: 44 88 4d 9b mov %r9b,-0x65(%rbp)
ndm->ndm_ifindex = vxlan->dev->ifindex;
1ae3: 44 88 45 9c mov %r8b,-0x64(%rbp)
1ae7: e8 00 00 00 00 callq 1aec <vxlan_fdb_info+0xfc>
1aec: 48 8d 4d b0 lea -0x50(%rbp),%rcx
ndm->ndm_flags = fdb->flags;
1af0: ba 04 00 00 00 mov $0x4,%edx
ndm->ndm_type = RTN_UNICAST;
1af5: be 0a 00 00 00 mov $0xa,%esi
send_eth = !is_zero_ether_addr(fdb->eth_addr);
} else
ndm->ndm_family = AF_BRIDGE;
ndm->ndm_state = fdb->state;
ndm->ndm_ifindex = vxlan->dev->ifindex;
ndm->ndm_flags = fdb->flags;
1afa: 4c 89 e7 mov %r12,%rdi
1afd: 89 45 b0 mov %eax,-0x50(%rbp)
ndm->ndm_type = RTN_UNICAST;
if (!net_eq(dev_net(vxlan->dev), vxlan->net) &&
1b00: e8 00 00 00 00 callq 1b05 <vxlan_fdb_info+0x115>
1b05: 85 c0 test %eax,%eax
1b07: 44 0f b6 45 9c movzbl -0x64(%rbp),%r8d
1b0c: 44 0f b6 4d 9b movzbl -0x65(%rbp),%r9d
1b11: 0f 85 32 01 00 00 jne 1c49 <vxlan_fdb_info+0x259>
nla_put_s32(skb, NDA_LINK_NETNSID,
1b17: 45 84 c9 test %r9b,%r9b
1b1a: 0f 85 72 01 00 00 jne 1c92 <vxlan_fdb_info+0x2a2>
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
{
return nla_put(skb, attrtype, sizeof(s32), &value);
1b20: 45 84 c0 test %r8b,%r8b
1b23: 0f 85 f0 00 00 00 jne 1c19 <vxlan_fdb_info+0x229>
1b29: 41 0f b7 46 1c movzwl 0x1c(%r14),%eax
1b2e: 66 85 c0 test %ax,%ax
1b31: 74 2c je 1b5f <vxlan_fdb_info+0x16f>
1b33: 66 41 3b 87 3c 01 00 cmp 0x13c(%r15),%ax
1b3a: 00
ndm->ndm_state = fdb->state;
ndm->ndm_ifindex = vxlan->dev->ifindex;
ndm->ndm_flags = fdb->flags;
ndm->ndm_type = RTN_UNICAST;
if (!net_eq(dev_net(vxlan->dev), vxlan->net) &&
1b3b: 74 22 je 1b5f <vxlan_fdb_info+0x16f>
1b3d: 48 8d 4d ae lea -0x52(%rbp),%rcx
1b41: ba 02 00 00 00 mov $0x2,%edx
1b46: be 06 00 00 00 mov $0x6,%esi
nla_put_s32(skb, NDA_LINK_NETNSID,
peernet2id_alloc(dev_net(vxlan->dev), vxlan->net)))
goto nla_put_failure;
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
1b4b: 4c 89 e7 mov %r12,%rdi
1b4e: 66 89 45 ae mov %ax,-0x52(%rbp)
goto nla_put_failure;
if (send_ip && vxlan_nla_put_addr(skb, NDA_DST, &rdst->remote_ip))
1b52: e8 00 00 00 00 callq 1b57 <vxlan_fdb_info+0x167>
1b57: 85 c0 test %eax,%eax
goto nla_put_failure;
if (rdst->remote_port && rdst->remote_port != vxlan->cfg.dst_port &&
1b59: 0f 85 ea 00 00 00 jne 1c49 <vxlan_fdb_info+0x259>
1b5f: 41 8b 46 20 mov 0x20(%r14),%eax
1b63: 41 3b 47 60 cmp 0x60(%r15),%eax
1b67: 74 23 je 1b8c <vxlan_fdb_info+0x19c>
1b69: 48 8d 4d b4 lea -0x4c(%rbp),%rcx
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
{
return nla_put(skb, attrtype, sizeof(__be16), &value);
1b6d: 0f c8 bswap %eax
1b6f: ba 04 00 00 00 mov $0x4,%edx
1b74: be 07 00 00 00 mov $0x7,%esi
1b79: 4c 89 e7 mov %r12,%rdi
1b7c: 89 45 b4 mov %eax,-0x4c(%rbp)
1b7f: e8 00 00 00 00 callq 1b84 <vxlan_fdb_info+0x194>
1b84: 85 c0 test %eax,%eax
1b86: 0f 85 bd 00 00 00 jne 1c49 <vxlan_fdb_info+0x259>
1b8c: 41 8b 46 24 mov 0x24(%r14),%eax
nla_put_be16(skb, NDA_PORT, rdst->remote_port))
goto nla_put_failure;
if (rdst->remote_vni != vxlan->default_dst.remote_vni &&
1b90: 85 c0 test %eax,%eax
1b92: 0f 85 d7 00 00 00 jne 1c6f <vxlan_fdb_info+0x27f>
1b98: 4c 8b 75 a0 mov -0x60(%rbp),%r14
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
{
return nla_put(skb, attrtype, sizeof(u32), &value);
1b9c: 4c 89 f7 mov %r14,%rdi
1b9f: 49 2b 7d 28 sub 0x28(%r13),%rdi
1ba3: e8 00 00 00 00 callq 1ba8 <vxlan_fdb_info+0x1b8>
1ba8: 4c 89 f7 mov %r14,%rdi
1bab: 49 2b 7d 20 sub 0x20(%r13),%rdi
1baf: 89 45 c4 mov %eax,-0x3c(%rbp)
1bb2: c7 45 c0 00 00 00 00 movl $0x0,-0x40(%rbp)
1bb9: e8 00 00 00 00 callq 1bbe <vxlan_fdb_info+0x1ce>
nla_put_u32(skb, NDA_VNI, be32_to_cpu(rdst->remote_vni)))
goto nla_put_failure;
if (rdst->remote_ifindex &&
1bbe: 48 8d 4d c0 lea -0x40(%rbp),%rcx
1bc2: ba 10 00 00 00 mov $0x10,%edx
1bc7: be 03 00 00 00 mov $0x3,%esi
nla_put_u32(skb, NDA_IFINDEX, rdst->remote_ifindex))
goto nla_put_failure;
ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
1bcc: 4c 89 e7 mov %r12,%rdi
1bcf: 89 45 c8 mov %eax,-0x38(%rbp)
1bd2: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%rbp)
ci.ndm_confirmed = 0;
ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
1bd9: e8 00 00 00 00 callq 1bde <vxlan_fdb_info+0x1ee>
1bde: 85 c0 test %eax,%eax
goto nla_put_failure;
if (rdst->remote_ifindex &&
nla_put_u32(skb, NDA_IFINDEX, rdst->remote_ifindex))
goto nla_put_failure;
ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
1be0: 75 67 jne 1c49 <vxlan_fdb_info+0x259>
ci.ndm_confirmed = 0;
1be2: 41 8b 94 24 c8 00 00 mov 0xc8(%r12),%edx
1be9: 00
ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
1bea: 49 03 94 24 d0 00 00 add 0xd0(%r12),%rdx
1bf1: 00
ci.ndm_refcnt = 0;
if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
1bf2: 48 29 da sub %rbx,%rdx
1bf5: 89 13 mov %edx,(%rbx)
1bf7: 48 8b 4d d0 mov -0x30(%rbp),%rcx
1bfb: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
1c02: 00 00
goto nla_put_failure;
ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
ci.ndm_confirmed = 0;
ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
ci.ndm_refcnt = 0;
1c04: 0f 85 23 01 00 00 jne 1d2d <vxlan_fdb_info+0x33d>
if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
1c0a: 48 83 c4 40 add $0x40,%rsp
1c0e: 5b pop %rbx
1c0f: 41 5c pop %r12
1c11: 41 5d pop %r13
* attributes. Only necessary if attributes have been added to
* the message.
*/
static inline void nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
{
nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh;
1c13: 41 5e pop %r14
1c15: 41 5f pop %r15
1c17: 5d pop %rbp
1c18: c3 retq
1c19: 66 41 83 3e 0a cmpw $0xa,(%r14)
1c1e: 0f 84 d0 00 00 00 je 1cf4 <vxlan_fdb_info+0x304>
1c24: 41 8b 46 04 mov 0x4(%r14),%eax
return 0;
nla_put_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
1c28: 48 8d 4d bc lea -0x44(%rbp),%rcx
1c2c: ba 04 00 00 00 mov $0x4,%edx
1c31: be 01 00 00 00 mov $0x1,%esi
1c36: 4c 89 e7 mov %r12,%rdi
1c39: 89 45 bc mov %eax,-0x44(%rbp)
1c3c: e8 00 00 00 00 callq 1c41 <vxlan_fdb_info+0x251>
1c41: 85 c0 test %eax,%eax
1c43: 0f 84 e0 fe ff ff je 1b29 <vxlan_fdb_info+0x139>
}
static int vxlan_nla_put_addr(struct sk_buff *skb, int attr,
const union vxlan_addr *ip)
{
if (ip->sa.sa_family == AF_INET6)
1c49: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
1c50: 00
1c51: 48 39 d8 cmp %rbx,%rax
1c54: 0f 87 b5 00 00 00 ja 1d0f <vxlan_fdb_info+0x31f>
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
{
return nla_put(skb, attrtype, sizeof(__be32), &value);
1c5a: 48 29 c3 sub %rax,%rbx
1c5d: 4c 89 e7 mov %r12,%rdi
1c60: 48 89 de mov %rbx,%rsi
1c63: e8 00 00 00 00 callq 1c68 <vxlan_fdb_info+0x278>
1c68: b8 a6 ff ff ff mov $0xffffffa6,%eax
1c6d: eb 88 jmp 1bf7 <vxlan_fdb_info+0x207>
1c6f: 48 8d 4d b8 lea -0x48(%rbp),%rcx
goto nla_put_failure;
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
goto nla_put_failure;
if (send_ip && vxlan_nla_put_addr(skb, NDA_DST, &rdst->remote_ip))
1c73: ba 04 00 00 00 mov $0x4,%edx
1c78: be 08 00 00 00 mov $0x8,%esi
* Trims the message to the provided mark.
*/
static inline void nlmsg_trim(struct sk_buff *skb, const void *mark)
{
if (mark) {
WARN_ON((unsigned char *) mark < skb->data);
1c7d: 4c 89 e7 mov %r12,%rdi
1c80: 89 45 b8 mov %eax,-0x48(%rbp)
1c83: e8 00 00 00 00 callq 1c88 <vxlan_fdb_info+0x298>
1c88: 85 c0 test %eax,%eax
skb_trim(skb, (unsigned char *) mark - skb->data);
1c8a: 0f 84 08 ff ff ff je 1b98 <vxlan_fdb_info+0x1a8>
1c90: eb b7 jmp 1c49 <vxlan_fdb_info+0x259>
1c92: 49 8d 4d 40 lea 0x40(%r13),%rcx
1c96: ba 06 00 00 00 mov $0x6,%edx
nlmsg_end(skb, nlh);
return 0;
nla_put_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
1c9b: be 02 00 00 00 mov $0x2,%esi
* @attrtype: attribute type
* @value: numeric value
*/
static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
{
return nla_put(skb, attrtype, sizeof(u32), &value);
1ca0: 4c 89 e7 mov %r12,%rdi
1ca3: 44 88 45 9c mov %r8b,-0x64(%rbp)
1ca7: e8 00 00 00 00 callq 1cac <vxlan_fdb_info+0x2bc>
1cac: 85 c0 test %eax,%eax
1cae: 44 0f b6 45 9c movzbl -0x64(%rbp),%r8d
1cb3: 0f 84 67 fe ff ff je 1b20 <vxlan_fdb_info+0x130>
nla_put_be16(skb, NDA_PORT, rdst->remote_port))
goto nla_put_failure;
if (rdst->remote_vni != vxlan->default_dst.remote_vni &&
nla_put_u32(skb, NDA_VNI, be32_to_cpu(rdst->remote_vni)))
goto nla_put_failure;
if (rdst->remote_ifindex &&
1cb9: eb 8e jmp 1c49 <vxlan_fdb_info+0x259>
1cbb: c6 40 10 02 movb $0x2,0x10(%rax)
1cbf: 66 41 83 3e 0a cmpw $0xa,(%r14)
if (!net_eq(dev_net(vxlan->dev), vxlan->net) &&
nla_put_s32(skb, NDA_LINK_NETNSID,
peernet2id_alloc(dev_net(vxlan->dev), vxlan->net)))
goto nla_put_failure;
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
1cc4: 74 20 je 1ce6 <vxlan_fdb_info+0x2f6>
1cc6: 41 8b 46 04 mov 0x4(%r14),%eax
1cca: 85 c0 test %eax,%eax
1ccc: 41 0f 94 c0 sete %r8b
1cd0: 41 0f b7 45 44 movzwl 0x44(%r13),%eax
1cd5: 41 83 f0 01 xor $0x1,%r8d
1cd9: 41 0b 45 40 or 0x40(%r13),%eax
1cdd: 41 0f 95 c1 setne %r9b
1ce1: e9 c3 fd ff ff jmpq 1aa9 <vxlan_fdb_info+0xb9>
1ce6: 49 8b 46 08 mov 0x8(%r14),%rax
1cea: 49 0b 46 10 or 0x10(%r14),%rax
memset(ndm, 0, sizeof(*ndm));
send_eth = send_ip = true;
if (type == RTM_GETNEIGH) {
ndm->ndm_family = AF_INET;
1cee: 41 0f 94 c0 sete %r8b
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
1cf2: eb dc jmp 1cd0 <vxlan_fdb_info+0x2e0>
1cf4: 49 8d 4e 08 lea 0x8(%r14),%rcx
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
1cf8: ba 10 00 00 00 mov $0x10,%edx
1cfd: be 01 00 00 00 mov $0x1,%esi
send_eth = send_ip = true;
if (type == RTM_GETNEIGH) {
ndm->ndm_family = AF_INET;
send_ip = !vxlan_addr_any(&rdst->remote_ip);
send_eth = !is_zero_ether_addr(fdb->eth_addr);
1d02: 4c 89 e7 mov %r12,%rdi
send_eth = send_ip = true;
if (type == RTM_GETNEIGH) {
ndm->ndm_family = AF_INET;
send_ip = !vxlan_addr_any(&rdst->remote_ip);
1d05: e8 00 00 00 00 callq 1d0a <vxlan_fdb_info+0x31a>
send_eth = !is_zero_ether_addr(fdb->eth_addr);
1d0a: e9 32 ff ff ff jmpq 1c41 <vxlan_fdb_info+0x251>
1d0f: be 16 02 00 00 mov $0x216,%esi
1d14: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
static inline bool ipv6_addr_any(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul = (const unsigned long *)a;
return (ul[0] | ul[1]) == 0UL;
1d1b: e8 00 00 00 00 callq 1d20 <vxlan_fdb_info+0x330>
1d20: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
1d27: 00
* @addr: IPv6 address
*/
static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
const struct in6_addr *addr)
{
return nla_put(skb, attrtype, sizeof(*addr), addr);
1d28: e9 2d ff ff ff jmpq 1c5a <vxlan_fdb_info+0x26a>
1d2d: e8 00 00 00 00 callq 1d32 <vxlan_fdb_info+0x342>
1d32: 0f 1f 40 00 nopl 0x0(%rax)
1d36: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
1d3d: 00 00 00
0000000000001d40 <vxlan_fdb_notify>:
* Trims the message to the provided mark.
*/
static inline void nlmsg_trim(struct sk_buff *skb, const void *mark)
{
if (mark) {
WARN_ON((unsigned char *) mark < skb->data);
1d40: e8 00 00 00 00 callq 1d45 <vxlan_fdb_notify+0x5>
1d45: 55 push %rbp
1d46: 48 89 e5 mov %rsp,%rbp
1d49: 41 57 push %r15
1d4b: 41 56 push %r14
1d4d: 41 55 push %r13
1d4f: 41 54 push %r12
1d51: 49 89 f6 mov %rsi,%r14
1d54: 53 push %rbx
1d55: 49 89 fc mov %rdi,%r12
1d58: 49 89 d7 mov %rdx,%r15
1d5b: be 20 00 08 02 mov $0x2080020,%esi
return 0;
nla_put_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
1d60: 31 d2 xor %edx,%edx
1d62: 48 83 ec 18 sub $0x18,%rsp
1d66: 48 8b 47 30 mov 0x30(%rdi),%rax
1d6a: 89 4d d4 mov %ecx,-0x2c(%rbp)
1d6d: bf 70 00 00 00 mov $0x70,%edi
+ nla_total_size(sizeof(struct nda_cacheinfo));
}
static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
struct vxlan_rdst *rd, int type)
{
1d72: b9 ff ff ff ff mov $0xffffffff,%ecx
1d77: 4c 8b a8 80 04 00 00 mov 0x480(%rax),%r13
1d7e: e8 00 00 00 00 callq 1d83 <vxlan_fdb_notify+0x43>
1d83: 48 85 c0 test %rax,%rax
1d86: 0f 84 83 00 00 00 je 1e0f <vxlan_fdb_notify+0xcf>
struct sk_buff *__build_skb(void *data, unsigned int frag_size);
struct sk_buff *build_skb(void *data, unsigned int frag_size);
static inline struct sk_buff *alloc_skb(unsigned int size,
gfp_t priority)
{
return __alloc_skb(size, priority, 0, NUMA_NO_NODE);
1d8c: 44 8b 4d d4 mov -0x2c(%rbp),%r9d
1d90: 45 31 c0 xor %r8d,%r8d
1d93: 31 c9 xor %ecx,%ecx
1d95: 4c 89 e6 mov %r12,%rsi
1d98: 4c 89 7c 24 08 mov %r15,0x8(%rsp)
1d9d: c7 04 24 00 00 00 00 movl $0x0,(%rsp)
1da4: 4c 89 f2 mov %r14,%rdx
1da7: 48 89 c7 mov %rax,%rdi
1daa: 48 89 c3 mov %rax,%rbx
1dad: e8 3e fc ff ff callq 19f0 <vxlan_fdb_info>
1db2: 85 c0 test %eax,%eax
struct net *net = dev_net(vxlan->dev);
struct sk_buff *skb;
int err = -ENOBUFS;
skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC);
if (skb == NULL)
1db4: 41 89 c4 mov %eax,%r12d
1db7: 79 2c jns 1de5 <vxlan_fdb_notify+0xa5>
1db9: 83 f8 a6 cmp $0xffffffa6,%eax
goto errout;
err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, rd);
1dbc: 74 59 je 1e17 <vxlan_fdb_notify+0xd7>
1dbe: 48 89 df mov %rbx,%rdi
1dc1: e8 00 00 00 00 callq 1dc6 <vxlan_fdb_notify+0x86>
1dc6: 44 89 e2 mov %r12d,%edx
1dc9: 4c 89 ef mov %r13,%rdi
1dcc: be 03 00 00 00 mov $0x3,%esi
1dd1: e8 00 00 00 00 callq 1dd6 <vxlan_fdb_notify+0x96>
1dd6: 48 83 c4 18 add $0x18,%rsp
1dda: 5b pop %rbx
1ddb: 41 5c pop %r12
1ddd: 41 5d pop %r13
1ddf: 41 5e pop %r14
1de1: 41 5f pop %r15
if (err < 0) {
1de3: 5d pop %rbp
skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC);
if (skb == NULL)
goto errout;
err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, rd);
1de4: c3 retq
1de5: 4c 89 ee mov %r13,%rsi
if (err < 0) {
1de8: 48 89 df mov %rbx,%rdi
/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
1deb: 41 b9 20 00 08 02 mov $0x2080020,%r9d
kfree_skb(skb);
1df1: 45 31 c0 xor %r8d,%r8d
1df4: b9 03 00 00 00 mov $0x3,%ecx
rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
return;
errout:
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
1df9: 31 d2 xor %edx,%edx
1dfb: e8 00 00 00 00 callq 1e00 <vxlan_fdb_notify+0xc0>
1e00: 48 83 c4 18 add $0x18,%rsp
1e04: 5b pop %rbx
1e05: 41 5c pop %r12
}
1e07: 41 5d pop %r13
1e09: 41 5e pop %r14
1e0b: 41 5f pop %r15
1e0d: 5d pop %rbp
1e0e: c3 retq
1e0f: 41 bc 97 ff ff ff mov $0xffffff97,%r12d
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
1e15: eb af jmp 1dc6 <vxlan_fdb_notify+0x86>
1e17: be 60 01 00 00 mov $0x160,%esi
1e1c: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
1e23: e8 00 00 00 00 callq 1e28 <vxlan_fdb_notify+0xe8>
1e28: eb 94 jmp 1dbe <vxlan_fdb_notify+0x7e>
1e2a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000001e30 <vxlan_fdb_destroy>:
return;
errout:
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
}
1e30: e8 00 00 00 00 callq 1e35 <vxlan_fdb_destroy+0x5>
1e35: 55 push %rbp
1e36: 48 89 e5 mov %rsp,%rbp
1e39: 41 54 push %r12
1e3b: 53 push %rbx
1e3c: 49 89 fc mov %rdi,%r12
static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
struct vxlan_rdst *rd, int type)
{
struct net *net = dev_net(vxlan->dev);
struct sk_buff *skb;
int err = -ENOBUFS;
1e3f: 48 89 f3 mov %rsi,%rbx
1e42: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
goto errout;
err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, rd);
if (err < 0) {
/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
1e47: 41 83 ac 24 ec 00 00 subl $0x1,0xec(%r12)
1e4e: 00 01
1e50: b9 1d 00 00 00 mov $0x1d,%ecx
1e55: 48 89 de mov %rbx,%rsi
1e58: 48 8b 43 30 mov 0x30(%rbx),%rax
1e5c: 4c 89 e7 mov %r12,%rdi
1e5f: 48 8d 50 d8 lea -0x28(%rax),%rdx
}
kfree(f);
}
static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
{
1e63: e8 d8 fe ff ff callq 1d40 <vxlan_fdb_notify>
1e68: 48 8b 03 mov (%rbx),%rax
1e6b: 48 8b 53 08 mov 0x8(%rbx),%rdx
1e6f: 48 85 c0 test %rax,%rax
1e72: 48 89 02 mov %rax,(%rdx)
1e75: 74 04 je 1e7b <vxlan_fdb_destroy+0x4b>
netdev_dbg(vxlan->dev,
"delete %pM\n", f->eth_addr);
--vxlan->addrcnt;
1e77: 48 89 50 08 mov %rdx,0x8(%rax)
1e7b: 48 b8 00 02 00 00 00 movabs $0xdead000000000200,%rax
1e82: 00 ad de
vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_DELNEIGH);
1e85: 48 8d 7b 10 lea 0x10(%rbx),%rdi
1e89: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
1e90: 48 89 43 08 mov %rax,0x8(%rbx)
1e94: e8 00 00 00 00 callq 1e99 <vxlan_fdb_destroy+0x69>
return !READ_ONCE(h->first);
}
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
1e99: 5b pop %rbx
1e9a: 41 5c pop %r12
struct hlist_node **pprev = n->pprev;
1e9c: 5d pop %rbp
1e9d: c3 retq
1e9e: 48 8d 4e 40 lea 0x40(%rsi),%rcx
1ea2: 48 8b 77 30 mov 0x30(%rdi),%rsi
WRITE_ONCE(*pprev, next);
if (next)
1ea6: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
* hlist_for_each_entry().
*/
static inline void hlist_del_rcu(struct hlist_node *n)
{
__hlist_del(n);
n->pprev = LIST_POISON2;
1ead: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
1eb4: e8 00 00 00 00 callq 1eb9 <vxlan_fdb_destroy+0x89>
hlist_del_rcu(&f->hlist);
call_rcu(&f->rcu, vxlan_fdb_free);
1eb9: eb 8c jmp 1e47 <vxlan_fdb_destroy+0x17>
1ebb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000001ec0 <vxlan_cleanup>:
1ec0: e8 00 00 00 00 callq 1ec5 <vxlan_cleanup+0x5>
1ec5: 55 push %rbp
1ec6: 48 89 e5 mov %rsp,%rbp
}
1ec9: 41 57 push %r15
1ecb: 41 56 push %r14
1ecd: 41 55 push %r13
kfree(f);
}
static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
{
netdev_dbg(vxlan->dev,
1ecf: 41 54 push %r12
1ed1: 53 push %rbx
1ed2: 48 83 ec 10 sub $0x10,%rsp
1ed6: 48 8b 47 30 mov 0x30(%rdi),%rax
1eda: 4c 8b 25 00 00 00 00 mov 0x0(%rip),%r12 # 1ee1 <vxlan_cleanup+0x21>
1ee1: 48 8b 40 48 mov 0x48(%rax),%rax
1ee5: a8 01 test $0x1,%al
1ee7: 0f 84 b3 00 00 00 je 1fa0 <vxlan_cleanup+0xe0>
1eed: 48 8d 87 e8 00 00 00 lea 0xe8(%rdi),%rax
return NETDEV_TX_OK;
}
/* Walk the forwarding table and purge stale entries */
static void vxlan_cleanup(unsigned long arg)
{
1ef4: 4c 8d af 60 01 00 00 lea 0x160(%rdi),%r13
1efb: 48 89 fb mov %rdi,%rbx
1efe: 49 81 c4 c4 09 00 00 add $0x9c4,%r12
1f05: 48 89 45 d0 mov %rax,-0x30(%rbp)
struct vxlan_dev *vxlan = (struct vxlan_dev *) arg;
unsigned long next_timer = jiffies + FDB_AGE_INTERVAL;
unsigned int h;
if (!netif_running(vxlan->dev))
1f09: 48 8d 87 60 09 00 00 lea 0x960(%rdi),%rax
/* Walk the forwarding table and purge stale entries */
static void vxlan_cleanup(unsigned long arg)
{
struct vxlan_dev *vxlan = (struct vxlan_dev *) arg;
unsigned long next_timer = jiffies + FDB_AGE_INTERVAL;
1f10: 48 89 45 c8 mov %rax,-0x38(%rbp)
1f14: 48 8b 7d d0 mov -0x30(%rbp),%rdi
unsigned int h;
if (!netif_running(vxlan->dev))
1f18: e8 00 00 00 00 callq 1f1d <vxlan_cleanup+0x5d>
1f1d: 4d 8b 7d 00 mov 0x0(%r13),%r15
1f21: 4d 85 ff test %r15,%r15
1f24: 75 24 jne 1f4a <vxlan_cleanup+0x8a>
1f26: eb 56 jmp 1f7e <vxlan_cleanup+0xbe>
1f28: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
1f2d: b8 04 00 00 00 mov $0x4,%eax
/* Walk the forwarding table and purge stale entries */
static void vxlan_cleanup(unsigned long arg)
{
struct vxlan_dev *vxlan = (struct vxlan_dev *) arg;
unsigned long next_timer = jiffies + FDB_AGE_INTERVAL;
1f32: 4c 89 fe mov %r15,%rsi
1f35: 48 89 df mov %rbx,%rdi
1f38: 66 41 89 47 46 mov %ax,0x46(%r15)
1f3d: e8 ee fe ff ff callq 1e30 <vxlan_fdb_destroy>
1f42: 4d 85 f6 test %r14,%r14
}
static __always_inline void spin_lock_bh(spinlock_t *lock)
{
raw_spin_lock_bh(&lock->rlock);
1f45: 4d 89 f7 mov %r14,%r15
1f48: 74 34 je 1f7e <vxlan_cleanup+0xbe>
1f4a: 41 f6 47 46 80 testb $0x80,0x46(%r15)
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct hlist_node *p, *n;
spin_lock_bh(&vxlan->hash_lock);
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
1f4f: 4d 8b 37 mov (%r15),%r14
1f52: 75 ee jne 1f42 <vxlan_cleanup+0x82>
1f54: 48 69 93 50 01 00 00 imul $0xfa,0x150(%rbx),%rdx
1f5b: fa 00 00 00
timeout = f->used + vxlan->cfg.age_interval * HZ;
if (time_before_eq(timeout, jiffies)) {
netdev_dbg(vxlan->dev,
"garbage collect %pM\n",
f->eth_addr);
f->state = NUD_STALE;
1f5f: 48 8b 0d 00 00 00 00 mov 0x0(%rip),%rcx # 1f66 <vxlan_cleanup+0xa6>
vxlan_fdb_destroy(vxlan, f);
1f66: 49 03 57 28 add 0x28(%r15),%rdx
timeout = f->used + vxlan->cfg.age_interval * HZ;
if (time_before_eq(timeout, jiffies)) {
netdev_dbg(vxlan->dev,
"garbage collect %pM\n",
f->eth_addr);
f->state = NUD_STALE;
1f6a: 48 39 d1 cmp %rdx,%rcx
vxlan_fdb_destroy(vxlan, f);
1f6d: 79 b9 jns 1f28 <vxlan_cleanup+0x68>
1f6f: 4c 39 e2 cmp %r12,%rdx
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct hlist_node *p, *n;
spin_lock_bh(&vxlan->hash_lock);
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
1f72: 4d 89 f7 mov %r14,%r15
1f75: 4c 0f 48 e2 cmovs %rdx,%r12
1f79: 4d 85 f6 test %r14,%r14
struct vxlan_fdb *f
= container_of(p, struct vxlan_fdb, hlist);
unsigned long timeout;
if (f->state & NUD_PERMANENT)
1f7c: 75 cc jne 1f4a <vxlan_cleanup+0x8a>
1f7e: 48 8b 7d d0 mov -0x30(%rbp),%rdi
1f82: 49 83 c5 08 add $0x8,%r13
continue;
timeout = f->used + vxlan->cfg.age_interval * HZ;
1f86: e8 00 00 00 00 callq 1f8b <vxlan_cleanup+0xcb>
1f8b: 4c 3b 6d c8 cmp -0x38(%rbp),%r13
if (time_before_eq(timeout, jiffies)) {
1f8f: 75 83 jne 1f14 <vxlan_cleanup+0x54>
1f91: 48 8d bb a0 00 00 00 lea 0xa0(%rbx),%rdi
unsigned long timeout;
if (f->state & NUD_PERMANENT)
continue;
timeout = f->used + vxlan->cfg.age_interval * HZ;
1f98: 4c 89 e6 mov %r12,%rsi
if (time_before_eq(timeout, jiffies)) {
1f9b: e8 00 00 00 00 callq 1fa0 <vxlan_cleanup+0xe0>
"garbage collect %pM\n",
f->eth_addr);
f->state = NUD_STALE;
vxlan_fdb_destroy(vxlan, f);
} else if (time_before(timeout, next_timer))
next_timer = timeout;
1fa0: 48 83 c4 10 add $0x10,%rsp
1fa4: 5b pop %rbx
1fa5: 41 5c pop %r12
1fa7: 41 5d pop %r13
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct hlist_node *p, *n;
spin_lock_bh(&vxlan->hash_lock);
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
1fa9: 41 5e pop %r14
1fab: 41 5f pop %r15
1fad: 5d pop %rbp
raw_spin_unlock(&lock->rlock);
}
static __always_inline void spin_unlock_bh(spinlock_t *lock)
{
raw_spin_unlock_bh(&lock->rlock);
1fae: c3 retq
1faf: 48 8b 73 30 mov 0x30(%rbx),%rsi
1fb3: 49 8d 4f 40 lea 0x40(%r15),%rcx
1fb7: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
unsigned int h;
if (!netif_running(vxlan->dev))
return;
for (h = 0; h < FDB_HASH_SIZE; ++h) {
1fbe: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
next_timer = timeout;
}
spin_unlock_bh(&vxlan->hash_lock);
}
mod_timer(&vxlan->age_timer, next_timer);
1fc5: e8 00 00 00 00 callq 1fca <vxlan_cleanup+0x10a>
1fca: e9 5e ff ff ff jmpq 1f2d <vxlan_cleanup+0x6d>
1fcf: 90 nop
0000000000001fd0 <vxlan_fdb_delete_default>:
}
1fd0: e8 00 00 00 00 callq 1fd5 <vxlan_fdb_delete_default+0x5>
1fd5: 55 push %rbp
1fd6: 48 89 e5 mov %rsp,%rbp
1fd9: 41 54 push %r12
1fdb: 4c 8d a7 e8 00 00 00 lea 0xe8(%rdi),%r12
if (f->state & NUD_PERMANENT)
continue;
timeout = f->used + vxlan->cfg.age_interval * HZ;
if (time_before_eq(timeout, jiffies)) {
netdev_dbg(vxlan->dev,
1fe2: 53 push %rbx
1fe3: 48 89 fb mov %rdi,%rbx
1fe6: 4c 89 e7 mov %r12,%rdi
1fe9: e8 00 00 00 00 callq 1fee <vxlan_fdb_delete_default+0x1e>
1fee: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
1ff5: 48 89 df mov %rbx,%rdi
1ff8: e8 03 e0 ff ff callq 0 <__vxlan_find_mac>
1ffd: 48 85 c0 test %rax,%rax
return 0;
}
static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan)
{
2000: 74 0b je 200d <vxlan_fdb_delete_default+0x3d>
2002: 48 89 c6 mov %rax,%rsi
2005: 48 89 df mov %rbx,%rdi
2008: e8 23 fe ff ff callq 1e30 <vxlan_fdb_destroy>
raw_spin_lock(&lock->rlock);
}
static __always_inline void spin_lock_bh(spinlock_t *lock)
{
raw_spin_lock_bh(&lock->rlock);
200d: 4c 89 e7 mov %r12,%rdi
2010: e8 00 00 00 00 callq 2015 <vxlan_fdb_delete_default+0x45>
2015: 5b pop %rbx
2016: 41 5c pop %r12
2018: 5d pop %rbp
2019: c3 retq
201a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000002020 <vxlan_uninit>:
struct vxlan_fdb *f;
spin_lock_bh(&vxlan->hash_lock);
f = __vxlan_find_mac(vxlan, all_zeros_mac);
2020: e8 00 00 00 00 callq 2025 <vxlan_uninit+0x5>
2025: 55 push %rbp
2026: 48 89 e5 mov %rsp,%rbp
2029: 53 push %rbx
202a: 48 89 fb mov %rdi,%rbx
if (f)
202d: 48 8d bf 40 08 00 00 lea 0x840(%rdi),%rdi
vxlan_fdb_destroy(vxlan, f);
2034: e8 97 ff ff ff callq 1fd0 <vxlan_fdb_delete_default>
2039: 48 8b bb 88 04 00 00 mov 0x488(%rbx),%rdi
raw_spin_unlock(&lock->rlock);
}
static __always_inline void spin_unlock_bh(spinlock_t *lock)
{
raw_spin_unlock_bh(&lock->rlock);
2040: e8 00 00 00 00 callq 2045 <vxlan_uninit+0x25>
spin_unlock_bh(&vxlan->hash_lock);
}
2045: 5b pop %rbx
2046: 5d pop %rbp
2047: c3 retq
2048: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
204f: 00
0000000000002050 <vxlan_ip_miss>:
static void vxlan_uninit(struct net_device *dev)
{
2050: e8 00 00 00 00 callq 2055 <vxlan_ip_miss+0x5>
2055: 55 push %rbp
2056: 48 89 fa mov %rdi,%rdx
2059: b9 0a 00 00 00 mov $0xa,%ecx
struct vxlan_dev *vxlan = netdev_priv(dev);
vxlan_fdb_delete_default(vxlan);
205e: 48 89 e5 mov %rsp,%rbp
2061: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
2065: 48 81 ec b0 00 00 00 sub $0xb0,%rsp
free_percpu(dev->tstats);
206c: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
2073: 00 00
}
2075: 48 89 84 24 a8 00 00 mov %rax,0xa8(%rsp)
207c: 00
207d: 31 c0 xor %eax,%eax
207f: 48 89 e7 mov %rsp,%rdi
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
}
static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa)
{
2082: f3 48 ab rep stos %rax,%es:(%rdi)
2085: b9 04 00 00 00 mov $0x4,%ecx
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb f = {
208a: 48 8d 7c 24 50 lea 0x50(%rsp),%rdi
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
}
static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa)
{
208f: 66 89 4c 24 46 mov %cx,0x46(%rsp)
2094: b9 0b 00 00 00 mov $0xb,%ecx
2099: f3 48 ab rep stos %rax,%es:(%rdi)
209c: 48 8b 06 mov (%rsi),%rax
209f: 48 8d ba 40 08 00 00 lea 0x840(%rdx),%rdi
20a6: 48 8d 54 24 50 lea 0x50(%rsp),%rdx
20ab: b9 1e 00 00 00 mov $0x1e,%ecx
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb f = {
20b0: c7 44 24 70 01 00 00 movl $0x1,0x70(%rsp)
20b7: 00
20b8: 48 89 44 24 50 mov %rax,0x50(%rsp)
.state = NUD_STALE,
};
struct vxlan_rdst remote = {
20bd: 48 8b 46 08 mov 0x8(%rsi),%rax
}
static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb f = {
20c1: 48 89 44 24 58 mov %rax,0x58(%rsp)
.state = NUD_STALE,
};
struct vxlan_rdst remote = {
20c6: 48 8b 46 10 mov 0x10(%rsi),%rax
20ca: 48 89 44 24 60 mov %rax,0x60(%rsp)
.remote_ip = *ipa, /* goes to NDA_DST */
.remote_vni = cpu_to_be32(VXLAN_N_VID),
};
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
20cf: 8b 46 18 mov 0x18(%rsi),%eax
20d2: 48 89 e6 mov %rsp,%rsi
20d5: 89 44 24 68 mov %eax,0x68(%rsp)
20d9: e8 62 fc ff ff callq 1d40 <vxlan_fdb_notify>
20de: 48 8b 84 24 a8 00 00 mov 0xa8(%rsp),%rax
20e5: 00
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb f = {
.state = NUD_STALE,
};
struct vxlan_rdst remote = {
20e6: 65 48 33 04 25 28 00 xor %gs:0x28,%rax
20ed: 00 00
20ef: 75 02 jne 20f3 <vxlan_ip_miss+0xa3>
20f1: c9 leaveq
20f2: c3 retq
20f3: e8 00 00 00 00 callq 20f8 <vxlan_ip_miss+0xa8>
20f8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
20ff: 00
0000000000002100 <vxlan_fdb_miss>:
2100: e8 00 00 00 00 callq 2105 <vxlan_fdb_miss+0x5>
2105: 55 push %rbp
2106: 49 89 f8 mov %rdi,%r8
.remote_ip = *ipa, /* goes to NDA_DST */
.remote_vni = cpu_to_be32(VXLAN_N_VID),
};
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
2109: b9 0a 00 00 00 mov $0xa,%ecx
}
210e: ba 04 00 00 00 mov $0x4,%edx
2113: 48 89 e5 mov %rsp,%rbp
2116: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
211a: 48 81 ec b0 00 00 00 sub $0xb0,%rsp
2121: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
2128: 00 00
212a: 48 89 84 24 a8 00 00 mov %rax,0xa8(%rsp)
2131: 00
static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
{
2132: 31 c0 xor %eax,%eax
2134: 48 89 e7 mov %rsp,%rdi
2137: f3 48 ab rep stos %rax,%es:(%rdi)
struct vxlan_fdb f = {
213a: 48 8d 7c 24 50 lea 0x50(%rsp),%rdi
213f: b9 0b 00 00 00 mov $0xb,%ecx
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
}
static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
{
2144: 66 89 54 24 46 mov %dx,0x46(%rsp)
2149: 48 8d 54 24 50 lea 0x50(%rsp),%rdx
214e: f3 48 ab rep stos %rax,%es:(%rdi)
2151: 8b 06 mov (%rsi),%eax
2153: b9 1e 00 00 00 mov $0x1e,%ecx
2158: 4c 89 c7 mov %r8,%rdi
215b: 89 44 24 40 mov %eax,0x40(%rsp)
215f: 0f b7 46 04 movzwl 0x4(%rsi),%eax
2163: 48 89 e6 mov %rsp,%rsi
struct vxlan_fdb f = {
2166: 66 89 44 24 44 mov %ax,0x44(%rsp)
.state = NUD_STALE,
};
struct vxlan_rdst remote = { };
216b: e8 d0 fb ff ff callq 1d40 <vxlan_fdb_notify>
2170: 48 8b 84 24 a8 00 00 mov 0xa8(%rsp),%rax
2177: 00
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
}
static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
{
struct vxlan_fdb f = {
2178: 65 48 33 04 25 28 00 xor %gs:0x28,%rax
217f: 00 00
.state = NUD_STALE,
};
struct vxlan_rdst remote = { };
memcpy(f.eth_addr, eth_addr, ETH_ALEN);
2181: 75 02 jne 2185 <vxlan_fdb_miss+0x85>
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
2183: c9 leaveq
2184: c3 retq
2185: e8 00 00 00 00 callq 218a <vxlan_fdb_miss+0x8a>
218a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000002190 <vxlan_fdb_dump>:
struct vxlan_fdb f = {
.state = NUD_STALE,
};
struct vxlan_rdst remote = { };
memcpy(f.eth_addr, eth_addr, ETH_ALEN);
2190: e8 00 00 00 00 callq 2195 <vxlan_fdb_dump+0x5>
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
2195: 55 push %rbp
struct vxlan_fdb f = {
.state = NUD_STALE,
};
struct vxlan_rdst remote = { };
memcpy(f.eth_addr, eth_addr, ETH_ALEN);
2196: 48 8d 82 40 08 00 00 lea 0x840(%rdx),%rax
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
219d: 48 89 e5 mov %rsp,%rbp
}
21a0: 41 57 push %r15
21a2: 41 56 push %r14
21a4: 41 55 push %r13
21a6: 41 54 push %r12
21a8: 49 89 f6 mov %rsi,%r14
21ab: 53 push %rbx
21ac: 44 89 c3 mov %r8d,%ebx
21af: 48 83 ec 30 sub $0x30,%rsp
21b3: 48 89 45 d0 mov %rax,-0x30(%rbp)
21b7: 48 8d 82 a0 09 00 00 lea 0x9a0(%rdx),%rax
21be: 48 89 7d c8 mov %rdi,-0x38(%rbp)
/* Dump forwarding table */
static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct net_device *dev,
struct net_device *filter_dev, int idx)
{
21c2: 48 89 45 c0 mov %rax,-0x40(%rbp)
21c6: 48 8d 82 a0 11 00 00 lea 0x11a0(%rdx),%rax
21cd: 48 89 45 b8 mov %rax,-0x48(%rbp)
21d1: 48 8b 45 c0 mov -0x40(%rbp),%rax
21d5: 4c 8b 28 mov (%rax),%r13
21d8: 4d 85 ed test %r13,%r13
21db: 0f 84 91 00 00 00 je 2272 <vxlan_fdb_dump+0xe2>
21e1: 49 8b 45 30 mov 0x30(%r13),%rax
21e5: 4d 8d 7d 30 lea 0x30(%r13),%r15
21e9: 49 39 c7 cmp %rax,%r15
21ec: 4c 8d 60 d8 lea -0x28(%rax),%r12
21f0: 74 73 je 2265 <vxlan_fdb_dump+0xd5>
21f2: 4c 89 f0 mov %r14,%rax
21f5: 4d 89 fe mov %r15,%r14
21f8: 49 89 c7 mov %rax,%r15
21fb: eb 11 jmp 220e <vxlan_fdb_dump+0x7e>
21fd: 49 8b 44 24 28 mov 0x28(%r12),%rax
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
2202: 83 c3 01 add $0x1,%ebx
2205: 49 39 c6 cmp %rax,%r14
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct vxlan_fdb *f;
int err;
hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
2208: 4c 8d 60 d8 lea -0x28(%rax),%r12
220c: 74 54 je 2262 <vxlan_fdb_dump+0xd2>
220e: 48 63 c3 movslq %ebx,%rax
2211: 49 3b 47 48 cmp 0x48(%r15),%rax
struct vxlan_rdst *rd;
list_for_each_entry_rcu(rd, &f->remotes, list) {
2215: 7c e6 jl 21fd <vxlan_fdb_dump+0x6d>
2217: 49 8b 47 08 mov 0x8(%r15),%rax
221b: 48 8b 75 d0 mov -0x30(%rbp),%rsi
221f: 41 b9 1c 00 00 00 mov $0x1c,%r9d
2225: 48 8b 7d c8 mov -0x38(%rbp),%rdi
2229: 4c 89 ea mov %r13,%rdx
222c: 44 8b 40 08 mov 0x8(%rax),%r8d
2230: 49 8b 07 mov (%r15),%rax
if (err < 0) {
cb->args[1] = err;
goto out;
}
skip:
++idx;
2233: 8b 48 34 mov 0x34(%rax),%ecx
int err;
hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
struct vxlan_rdst *rd;
list_for_each_entry_rcu(rd, &f->remotes, list) {
2236: 4c 89 64 24 08 mov %r12,0x8(%rsp)
223b: c7 04 24 02 00 00 00 movl $0x2,(%rsp)
if (idx < cb->args[0])
2242: e8 a9 f7 ff ff callq 19f0 <vxlan_fdb_info>
goto skip;
err = vxlan_fdb_info(skb, vxlan, f,
2247: 85 c0 test %eax,%eax
2249: 79 b2 jns 21fd <vxlan_fdb_dump+0x6d>
224b: 48 98 cltq
224d: 49 89 47 50 mov %rax,0x50(%r15)
2251: 48 83 c4 30 add $0x30,%rsp
2255: 89 d8 mov %ebx,%eax
2257: 5b pop %rbx
2258: 41 5c pop %r12
225a: 41 5d pop %r13
225c: 41 5e pop %r14
225e: 41 5f pop %r15
2260: 5d pop %rbp
2261: c3 retq
2262: 4d 89 fe mov %r15,%r14
2265: 4d 8b 6d 00 mov 0x0(%r13),%r13
2269: 4d 85 ed test %r13,%r13
226c: 0f 85 6f ff ff ff jne 21e1 <vxlan_fdb_dump+0x51>
2272: 48 83 45 c0 08 addq $0x8,-0x40(%rbp)
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH,
NLM_F_MULTI, rd);
if (err < 0) {
2277: 48 8b 45 c0 mov -0x40(%rbp),%rax
cb->args[1] = err;
227b: 48 39 45 b8 cmp %rax,-0x48(%rbp)
227f: 0f 85 4c ff ff ff jne 21d1 <vxlan_fdb_dump+0x41>
}
}
}
out:
return idx;
}
2285: eb ca jmp 2251 <vxlan_fdb_dump+0xc1>
2287: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
228e: 00 00
0000000000002290 <vxlan_fdb_find_rdst>:
2290: e8 00 00 00 00 callq 2295 <vxlan_fdb_find_rdst+0x5>
2295: 55 push %rbp
2296: 4c 8b 4f 30 mov 0x30(%rdi),%r9
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct vxlan_fdb *f;
int err;
hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
229a: 48 83 c7 30 add $0x30,%rdi
229e: 48 89 e5 mov %rsp,%rbp
22a1: 4c 39 cf cmp %r9,%rdi
22a4: 74 61 je 2307 <vxlan_fdb_find_rdst+0x77>
22a6: 49 8d 41 d8 lea -0x28(%r9),%rax
22aa: 44 0f b7 16 movzwl (%rsi),%r10d
struct net_device *filter_dev, int idx)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned int h;
for (h = 0; h < FDB_HASH_SIZE; ++h) {
22ae: eb 0d jmp 22bd <vxlan_fdb_find_rdst+0x2d>
22b0: 4c 8b 48 28 mov 0x28(%rax),%r9
22b4: 4c 39 cf cmp %r9,%rdi
22b7: 49 8d 41 d8 lea -0x28(%r9),%rax
22bb: 74 4a je 2307 <vxlan_fdb_find_rdst+0x77>
22bd: 66 44 3b 10 cmp (%rax),%r10w
/* caller should hold vxlan->hash_lock */
static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port,
__be32 vni, __u32 ifindex)
{
22c1: 75 ed jne 22b0 <vxlan_fdb_find_rdst+0x20>
22c3: 66 41 83 fa 0a cmp $0xa,%r10w
struct vxlan_rdst *rd;
list_for_each_entry(rd, &f->remotes, list) {
22c8: 74 24 je 22ee <vxlan_fdb_find_rdst+0x5e>
22ca: 44 8b 5e 04 mov 0x4(%rsi),%r11d
/* caller should hold vxlan->hash_lock */
static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port,
__be32 vni, __u32 ifindex)
{
22ce: 44 39 58 04 cmp %r11d,0x4(%rax)
struct vxlan_rdst *rd;
list_for_each_entry(rd, &f->remotes, list) {
22d2: 41 0f 94 c1 sete %r9b
22d6: 45 84 c9 test %r9b,%r9b
22d9: 74 d5 je 22b0 <vxlan_fdb_find_rdst+0x20>
22db: 66 39 50 1c cmp %dx,0x1c(%rax)
22df: 75 cf jne 22b0 <vxlan_fdb_find_rdst+0x20>
22e1: 39 48 20 cmp %ecx,0x20(%rax)
22e4: 75 ca jne 22b0 <vxlan_fdb_find_rdst+0x20>
22e6: 44 39 40 24 cmp %r8d,0x24(%rax)
22ea: 75 c4 jne 22b0 <vxlan_fdb_find_rdst+0x20>
22ec: 5d pop %rbp
#if IS_ENABLED(CONFIG_IPV6)
static inline
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
{
if (a->sa.sa_family != b->sa.sa_family)
22ed: c3 retq
22ee: 4c 8b 58 08 mov 0x8(%rax),%r11
22f2: 4c 8b 48 10 mov 0x10(%rax),%r9
return false;
if (a->sa.sa_family == AF_INET6)
22f6: 4c 33 5e 08 xor 0x8(%rsi),%r11
return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
else
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
22fa: 4c 33 4e 10 xor 0x10(%rsi),%r9
22fe: 4d 09 cb or %r9,%r11
2301: 41 0f 94 c1 sete %r9b
2305: eb cf jmp 22d6 <vxlan_fdb_find_rdst+0x46>
__be32 vni, __u32 ifindex)
{
struct vxlan_rdst *rd;
list_for_each_entry(rd, &f->remotes, list) {
if (vxlan_addr_equal(&rd->remote_ip, ip) &&
2307: 31 c0 xor %eax,%eax
2309: 5d pop %rbp
230a: c3 retq
230b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000002310 <vxlan_fdb_delete>:
2310: e8 00 00 00 00 callq 2315 <vxlan_fdb_delete+0x5>
rd->remote_port == port &&
2315: 55 push %rbp
rd->remote_vni == vni &&
2316: 48 89 f7 mov %rsi,%rdi
2319: 48 89 e5 mov %rsp,%rbp
rd->remote_ifindex == ifindex)
return rd;
}
return NULL;
}
231c: 41 57 push %r15
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul1 = (const unsigned long *)a1;
const unsigned long *ul2 = (const unsigned long *)a2;
return ((ul1[0] ^ ul2[0]) | (ul1[1] ^ ul2[1])) == 0UL;
231e: 41 56 push %r14
2320: 41 55 push %r13
2322: 41 54 push %r12
2324: 4c 8d b2 40 08 00 00 lea 0x840(%rdx),%r14
232b: 53 push %rbx
232c: 49 89 d4 mov %rdx,%r12
232f: 49 89 cf mov %rcx,%r15
2332: 4c 89 f6 mov %r14,%rsi
2335: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
2339: 48 83 ec 40 sub $0x40,%rsp
233d: 4c 8d 4c 24 0c lea 0xc(%rsp),%r9
/* Delete entry (via netlink) */
static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid)
{
2342: 4c 8d 44 24 08 lea 0x8(%rsp),%r8
2347: 48 8d 4c 24 06 lea 0x6(%rsp),%rcx
234c: 48 8d 54 24 10 lea 0x10(%rsp),%rdx
2351: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
2358: 00 00
235a: 48 89 44 24 38 mov %rax,0x38(%rsp)
235f: 31 c0 xor %eax,%eax
2361: e8 ba e2 ff ff callq 620 <vxlan_fdb_parse>
2366: 85 c0 test %eax,%eax
2368: 89 c3 mov %eax,%ebx
236a: 74 25 je 2391 <vxlan_fdb_delete+0x81>
236c: 89 d8 mov %ebx,%eax
__be16 port;
__be32 vni;
u32 ifindex;
int err;
err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
236e: 48 8b 5c 24 38 mov 0x38(%rsp),%rbx
2373: 65 48 33 1c 25 28 00 xor %gs:0x28,%rbx
237a: 00 00
237c: 0f 85 10 01 00 00 jne 2492 <vxlan_fdb_delete+0x182>
/* Delete entry (via netlink) */
static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid)
{
2382: 48 8d 65 d8 lea -0x28(%rbp),%rsp
2386: 5b pop %rbx
2387: 41 5c pop %r12
2389: 41 5d pop %r13
238b: 41 5e pop %r14
238d: 41 5f pop %r15
238f: 5d pop %rbp
2390: c3 retq
__be16 port;
__be32 vni;
u32 ifindex;
int err;
err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
2391: 4d 8d ac 24 28 09 00 lea 0x928(%r12),%r13
2398: 00
2399: 4c 89 ef mov %r13,%rdi
out:
spin_unlock_bh(&vxlan->hash_lock);
return err;
}
239c: e8 00 00 00 00 callq 23a1 <vxlan_fdb_delete+0x91>
23a1: 4c 89 fe mov %r15,%rsi
23a4: 4c 89 f7 mov %r14,%rdi
23a7: e8 54 dc ff ff callq 0 <__vxlan_find_mac>
23ac: 48 85 c0 test %rax,%rax
23af: 49 89 c4 mov %rax,%r12
23b2: 0f 84 d0 00 00 00 je 2488 <vxlan_fdb_delete+0x178>
23b8: 66 83 7c 24 10 0a cmpw $0xa,0x10(%rsp)
23be: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 23c5 <vxlan_fdb_delete+0xb5>
raw_spin_lock(&lock->rlock);
}
static __always_inline void spin_lock_bh(spinlock_t *lock)
{
raw_spin_lock_bh(&lock->rlock);
23c5: 49 89 44 24 28 mov %rax,0x28(%r12)
23ca: 0f 84 a6 00 00 00 je 2476 <vxlan_fdb_delete+0x166>
23d0: 8b 44 24 14 mov 0x14(%rsp),%eax
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
23d4: 85 c0 test %eax,%eax
23d6: 0f 94 c0 sete %al
23d9: 84 c0 test %al,%al
23db: 74 18 je 23f5 <vxlan_fdb_delete+0xe5>
if (f)
23dd: 4c 89 e6 mov %r12,%rsi
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
23e0: 4c 89 f7 mov %r14,%rdi
if (f)
23e3: e8 48 fa ff ff callq 1e30 <vxlan_fdb_destroy>
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
23e8: 4c 89 ef mov %r13,%rdi
23eb: e8 00 00 00 00 callq 23f0 <vxlan_fdb_delete+0xe0>
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
if (f)
f->used = jiffies;
23f0: e9 77 ff ff ff jmpq 236c <vxlan_fdb_delete+0x5c>
23f5: 0f b7 54 24 06 movzwl 0x6(%rsp),%edx
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
23fa: 44 8b 44 24 0c mov 0xc(%rsp),%r8d
23ff: 48 8d 74 24 10 lea 0x10(%rsp),%rsi
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
2404: 8b 4c 24 08 mov 0x8(%rsp),%ecx
2408: 4c 89 e7 mov %r12,%rdi
spin_lock_bh(&vxlan->hash_lock);
f = vxlan_find_mac(vxlan, addr);
if (!f)
goto out;
if (!vxlan_addr_any(&ip)) {
240b: e8 80 fe ff ff callq 2290 <vxlan_fdb_find_rdst>
vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
kfree_rcu(rd, rcu);
goto out;
}
vxlan_fdb_destroy(vxlan, f);
2410: 48 85 c0 test %rax,%rax
2413: 49 89 c7 mov %rax,%r15
2416: 74 70 je 2488 <vxlan_fdb_delete+0x178>
raw_spin_unlock(&lock->rlock);
}
static __always_inline void spin_unlock_bh(spinlock_t *lock)
{
raw_spin_unlock_bh(&lock->rlock);
2418: 49 8b 44 24 30 mov 0x30(%r12),%rax
241d: 49 8d 54 24 30 lea 0x30(%r12),%rdx
out:
spin_unlock_bh(&vxlan->hash_lock);
return err;
2422: 48 39 c2 cmp %rax,%rdx
f = vxlan_find_mac(vxlan, addr);
if (!f)
goto out;
if (!vxlan_addr_any(&ip)) {
rd = vxlan_fdb_find_rdst(f, &ip, port, vni, ifindex);
2425: 74 0c je 2433 <vxlan_fdb_delete+0x123>
2427: 49 8b 44 24 38 mov 0x38(%r12),%rax
242c: 49 39 44 24 30 cmp %rax,0x30(%r12)
2431: 74 aa je 23dd <vxlan_fdb_delete+0xcd>
2433: 49 8b 47 30 mov 0x30(%r15),%rax
2437: 49 8b 57 28 mov 0x28(%r15),%rdx
243b: 4c 89 e6 mov %r12,%rsi
243e: 4c 89 f7 mov %r14,%rdi
if (!rd)
2441: b9 1d 00 00 00 mov $0x1d,%ecx
2446: 48 89 42 08 mov %rax,0x8(%rdx)
244a: 48 89 10 mov %rdx,(%rax)
err = 0;
/* remove a destination if it's not the only one on the list,
* otherwise destroy the fdb entry
*/
if (rd && !list_is_singular(&f->remotes)) {
244d: 48 b8 00 02 00 00 00 movabs $0xdead000000000200,%rax
2454: 00 ad de
* list_is_singular - tests whether a list has just one entry.
* @head: the list to test.
*/
static inline int list_is_singular(const struct list_head *head)
{
return !list_empty(head) && (head->next == head->prev);
2457: 49 89 47 30 mov %rax,0x30(%r15)
245b: 4c 89 fa mov %r15,%rdx
245e: e8 dd f8 ff ff callq 1d40 <vxlan_fdb_notify>
* in an undefined state.
*/
#ifndef CONFIG_DEBUG_LIST
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
2463: 49 8d 7f 38 lea 0x38(%r15),%rdi
2467: be 38 00 00 00 mov $0x38,%esi
list_del_rcu(&rd->list);
vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
246c: e8 00 00 00 00 callq 2471 <vxlan_fdb_delete+0x161>
2471: e9 72 ff ff ff jmpq 23e8 <vxlan_fdb_delete+0xd8>
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
2476: 48 8b 44 24 18 mov 0x18(%rsp),%rax
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
247b: 48 0b 44 24 20 or 0x20(%rsp),%rax
* grace period has elapsed.
*/
static inline void list_del_rcu(struct list_head *entry)
{
__list_del_entry(entry);
entry->prev = LIST_POISON2;
2480: 0f 94 c0 sete %al
2483: e9 51 ff ff ff jmpq 23d9 <vxlan_fdb_delete+0xc9>
2488: bb fe ff ff ff mov $0xfffffffe,%ebx
248d: e9 56 ff ff ff jmpq 23e8 <vxlan_fdb_delete+0xd8>
2492: e8 00 00 00 00 callq 2497 <vxlan_fdb_delete+0x187>
kfree_rcu(rd, rcu);
2497: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
249e: 00 00
00000000000024a0 <vxlan_fdb_append>:
24a0: e8 00 00 00 00 callq 24a5 <vxlan_fdb_append+0x5>
goto out;
24a5: 55 push %rbp
static inline bool ipv6_addr_any(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul = (const unsigned long *)a;
return (ul[0] | ul[1]) == 0UL;
24a6: 48 89 e5 mov %rsp,%rbp
24a9: 41 57 push %r15
24ab: 41 56 push %r14
24ad: 41 55 push %r13
24af: 41 54 push %r12
24b1: 41 89 d6 mov %edx,%r14d
24b4: 53 push %rbx
24b5: 0f b7 d2 movzwl %dx,%edx
err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
if (err)
return err;
err = -ENOENT;
24b8: 48 89 fb mov %rdi,%rbx
24bb: 49 89 f7 mov %rsi,%r15
24be: 41 89 cd mov %ecx,%r13d
24c1: 45 89 c4 mov %r8d,%r12d
out:
spin_unlock_bh(&vxlan->hash_lock);
return err;
}
24c4: 48 83 ec 10 sub $0x10,%rsp
24c8: 4c 89 4d d0 mov %r9,-0x30(%rbp)
24cc: e8 bf fd ff ff callq 2290 <vxlan_fdb_find_rdst>
/* Add/update destinations for multicast */
static int vxlan_fdb_append(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port, __be32 vni,
__u32 ifindex, struct vxlan_rdst **rdp)
{
24d1: 31 d2 xor %edx,%edx
24d3: 48 85 c0 test %rax,%rax
24d6: 74 11 je 24e9 <vxlan_fdb_append+0x49>
24d8: 48 83 c4 10 add $0x10,%rsp
24dc: 89 d0 mov %edx,%eax
24de: 5b pop %rbx
24df: 41 5c pop %r12
24e1: 41 5d pop %r13
24e3: 41 5e pop %r14
struct vxlan_rdst *rd;
rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
24e5: 41 5f pop %r15
24e7: 5d pop %rbp
/* Add/update destinations for multicast */
static int vxlan_fdb_append(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port, __be32 vni,
__u32 ifindex, struct vxlan_rdst **rdp)
{
24e8: c3 retq
24e9: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # 24f0 <vxlan_fdb_append+0x50>
24f0: ba 58 00 00 00 mov $0x58,%edx
24f5: be 20 00 08 02 mov $0x2080020,%esi
24fa: e8 00 00 00 00 callq 24ff <vxlan_fdb_append+0x5f>
struct vxlan_rdst *rd;
rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
24ff: 48 85 c0 test %rax,%rax
if (rd)
return 0;
2502: 74 70 je 2574 <vxlan_fdb_append+0xd4>
__u32 ifindex, struct vxlan_rdst **rdp)
{
struct vxlan_rdst *rd;
rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
if (rd)
2504: 48 8d 78 48 lea 0x48(%rax),%rdi
list_add_tail_rcu(&rd->list, &f->remotes);
*rdp = rd;
return 1;
}
2508: be 20 00 08 02 mov $0x2080020,%esi
250d: 48 89 45 c8 mov %rax,-0x38(%rbp)
2511: e8 00 00 00 00 callq 2516 <vxlan_fdb_append+0x76>
2516: 85 c0 test %eax,%eax
2518: 48 8b 55 c8 mov -0x38(%rbp),%rdx
int index = kmalloc_index(size);
if (!index)
return ZERO_SIZE_PTR;
return kmem_cache_alloc_trace(kmalloc_caches[index],
251c: 75 60 jne 257e <vxlan_fdb_append+0xde>
251e: 49 8b 07 mov (%r15),%rax
2521: 48 8b 4b 38 mov 0x38(%rbx),%rcx
2525: 48 8d 73 30 lea 0x30(%rbx),%rsi
2529: 66 44 89 72 1c mov %r14w,0x1c(%rdx)
252e: 44 89 6a 20 mov %r13d,0x20(%rdx)
rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
if (rd)
return 0;
rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
if (rd == NULL)
2532: 44 89 62 24 mov %r12d,0x24(%rdx)
return -ENOBUFS;
if (dst_cache_init(&rd->dst_cache, GFP_ATOMIC)) {
2536: 48 89 72 28 mov %rsi,0x28(%rdx)
253a: 48 89 02 mov %rax,(%rdx)
253d: 49 8b 47 08 mov 0x8(%r15),%rax
2541: 48 89 4a 30 mov %rcx,0x30(%rdx)
2545: 48 89 42 08 mov %rax,0x8(%rdx)
2549: 49 8b 47 10 mov 0x10(%r15),%rax
254d: 48 89 42 10 mov %rax,0x10(%rdx)
* list_for_each_entry_rcu().
*/
static inline void list_add_tail_rcu(struct list_head *new,
struct list_head *head)
{
__list_add_rcu(new, head->prev, head);
2551: 41 8b 47 18 mov 0x18(%r15),%eax
rd->remote_ip = *ip;
rd->remote_port = port;
rd->remote_vni = vni;
rd->remote_ifindex = ifindex;
list_add_tail_rcu(&rd->list, &f->remotes);
2555: 89 42 18 mov %eax,0x18(%rdx)
2558: 48 8d 42 28 lea 0x28(%rdx),%rax
kfree(rd);
return -ENOBUFS;
}
rd->remote_ip = *ip;
rd->remote_port = port;
255c: 48 89 01 mov %rax,(%rcx)
rd->remote_vni = vni;
255f: 48 89 43 38 mov %rax,0x38(%rbx)
rd->remote_ifindex = ifindex;
2563: 48 8b 45 d0 mov -0x30(%rbp),%rax
list_add_tail_rcu(&rd->list, &f->remotes);
2567: 48 89 10 mov %rdx,(%rax)
if (dst_cache_init(&rd->dst_cache, GFP_ATOMIC)) {
kfree(rd);
return -ENOBUFS;
}
rd->remote_ip = *ip;
256a: ba 01 00 00 00 mov $0x1,%edx
256f: e9 64 ff ff ff jmpq 24d8 <vxlan_fdb_append+0x38>
#ifndef CONFIG_DEBUG_LIST
static inline void __list_add_rcu(struct list_head *new,
struct list_head *prev, struct list_head *next)
{
new->next = next;
new->prev = prev;
2574: ba 97 ff ff ff mov $0xffffff97,%edx
2579: e9 5a ff ff ff jmpq 24d8 <vxlan_fdb_append+0x38>
257e: 48 89 d7 mov %rdx,%rdi
2581: e8 00 00 00 00 callq 2586 <vxlan_fdb_append+0xe6>
2586: ba 97 ff ff ff mov $0xffffff97,%edx
rd->remote_port = port;
rd->remote_vni = vni;
rd->remote_ifindex = ifindex;
list_add_tail_rcu(&rd->list, &f->remotes);
258b: e9 48 ff ff ff jmpq 24d8 <vxlan_fdb_append+0x38>
0000000000002590 <vxlan_fdb_create>:
rcu_assign_pointer(list_next_rcu(prev), new);
next->prev = new;
2590: e8 00 00 00 00 callq 2595 <vxlan_fdb_create+0x5>
*rdp = rd;
2595: 55 push %rbp
2596: 48 89 e5 mov %rsp,%rbp
2599: 41 57 push %r15
return 1;
259b: 41 56 push %r14
259d: 41 55 push %r13
259f: 41 54 push %r12
25a1: 49 89 f7 mov %rsi,%r15
if (rd)
return 0;
rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
if (rd == NULL)
return -ENOBUFS;
25a4: 53 push %rbx
25a5: 49 89 fc mov %rdi,%r12
25a8: 45 89 c5 mov %r8d,%r13d
25ab: 48 83 ec 20 sub $0x20,%rsp
if (dst_cache_init(&rd->dst_cache, GFP_ATOMIC)) {
kfree(rd);
25af: 48 89 55 b8 mov %rdx,-0x48(%rbp)
25b3: 89 4d c4 mov %ecx,-0x3c(%rbp)
return -ENOBUFS;
25b6: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
25bd: 00 00
25bf: 48 89 45 d0 mov %rax,-0x30(%rbp)
static int vxlan_fdb_create(struct vxlan_dev *vxlan,
const u8 *mac, union vxlan_addr *ip,
__u16 state, __u16 flags,
__be16 port, __be32 vni, __u32 ifindex,
__u8 ndm_flags)
{
25c3: 31 c0 xor %eax,%eax
25c5: 44 89 4d c0 mov %r9d,-0x40(%rbp)
25c9: 44 8b 75 20 mov 0x20(%rbp),%r14d
25cd: 48 c7 45 c8 00 00 00 movq $0x0,-0x38(%rbp)
25d4: 00
25d5: e8 26 da ff ff callq 0 <__vxlan_find_mac>
25da: 48 85 c0 test %rax,%rax
25dd: 0f 84 41 01 00 00 je 2724 <vxlan_fdb_create+0x194>
25e3: 41 f7 c5 00 02 00 00 test $0x200,%r13d
25ea: 0f 85 e6 00 00 00 jne 26d6 <vxlan_fdb_create+0x146>
25f0: 48 89 c3 mov %rax,%rbx
25f3: 45 31 ff xor %r15d,%r15d
25f6: 8b 45 c4 mov -0x3c(%rbp),%eax
25f9: 66 39 43 46 cmp %ax,0x46(%rbx)
struct vxlan_rdst *rd = NULL;
25fd: 74 15 je 2614 <vxlan_fdb_create+0x84>
25ff: 66 89 43 46 mov %ax,0x46(%rbx)
2603: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 260a <vxlan_fdb_create+0x7a>
struct vxlan_fdb *f;
int notify = 0;
f = __vxlan_find_mac(vxlan, mac);
if (f) {
260a: 41 bf 01 00 00 00 mov $0x1,%r15d
2610: 48 89 43 20 mov %rax,0x20(%rbx)
if (flags & NLM_F_EXCL) {
2614: 44 38 73 48 cmp %r14b,0x48(%rbx)
2618: 74 15 je 262f <vxlan_fdb_create+0x9f>
261a: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 2621 <vxlan_fdb_create+0x91>
2621: 44 88 73 48 mov %r14b,0x48(%rbx)
__be16 port, __be32 vni, __u32 ifindex,
__u8 ndm_flags)
{
struct vxlan_rdst *rd = NULL;
struct vxlan_fdb *f;
int notify = 0;
2625: 41 bf 01 00 00 00 mov $0x1,%r15d
if (flags & NLM_F_EXCL) {
netdev_dbg(vxlan->dev,
"lost race to create %pM\n", mac);
return -EEXIST;
}
if (f->state != state) {
262b: 48 89 43 20 mov %rax,0x20(%rbx)
f->state = state;
262f: 41 f7 c5 00 01 00 00 test $0x100,%r13d
f->updated = jiffies;
2636: 74 3c je 2674 <vxlan_fdb_create+0xe4>
2638: 8b 43 40 mov 0x40(%rbx),%eax
notify = 1;
263b: a8 01 test $0x1,%al
263d: 0f 85 0f 02 00 00 jne 2852 <vxlan_fdb_create+0x2c2>
"lost race to create %pM\n", mac);
return -EEXIST;
}
if (f->state != state) {
f->state = state;
f->updated = jiffies;
2643: 0f b7 53 44 movzwl 0x44(%rbx),%edx
notify = 1;
}
if (f->flags != ndm_flags) {
2647: 09 c2 or %eax,%edx
2649: 0f 84 03 02 00 00 je 2852 <vxlan_fdb_create+0x2c2>
f->flags = ndm_flags;
f->updated = jiffies;
264f: 0f b7 55 c0 movzwl -0x40(%rbp),%edx
f->state = state;
f->updated = jiffies;
notify = 1;
}
if (f->flags != ndm_flags) {
f->flags = ndm_flags;
2653: 44 8b 45 18 mov 0x18(%rbp),%r8d
f->updated = jiffies;
notify = 1;
2657: 48 89 df mov %rbx,%rdi
265a: 8b 4d 10 mov 0x10(%rbp),%ecx
f->updated = jiffies;
notify = 1;
}
if (f->flags != ndm_flags) {
f->flags = ndm_flags;
f->updated = jiffies;
265d: 48 8b 75 b8 mov -0x48(%rbp),%rsi
notify = 1;
}
if ((flags & NLM_F_REPLACE)) {
2661: e8 2a fc ff ff callq 2290 <vxlan_fdb_find_rdst>
2666: 31 d2 xor %edx,%edx
* By definition the broadcast address is also a multicast address.
*/
static inline bool is_multicast_ether_addr(const u8 *addr)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
u32 a = *(const u32 *)addr;
2668: 48 85 c0 test %rax,%rax
/* Only change unicasts */
if (!(is_multicast_ether_addr(f->eth_addr) ||
266b: 0f 84 fc 01 00 00 je 286d <vxlan_fdb_create+0x2dd>
2671: 41 09 d7 or %edx,%r15d
2674: 41 81 e5 00 08 00 00 and $0x800,%r13d
267b: 74 31 je 26ae <vxlan_fdb_create+0x11e>
267d: 8b 43 40 mov 0x40(%rbx),%eax
union vxlan_addr *ip, __be16 port, __be32 vni,
__u32 ifindex)
{
struct vxlan_rdst *rd;
rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
2680: a8 01 test $0x1,%al
2682: 75 08 jne 268c <vxlan_fdb_create+0xfc>
2684: 0f b7 53 44 movzwl 0x44(%rbx),%edx
2688: 09 c2 or %eax,%edx
268a: 75 22 jne 26ae <vxlan_fdb_create+0x11e>
268c: 0f b7 55 c0 movzwl -0x40(%rbp),%edx
2690: 44 8b 45 18 mov 0x18(%rbp),%r8d
2694: 4c 8d 4d c8 lea -0x38(%rbp),%r9
if (rd)
2698: 8b 4d 10 mov 0x10(%rbp),%ecx
269b: 48 8b 75 b8 mov -0x48(%rbp),%rsi
269f: 48 89 df mov %rbx,%rdi
}
if ((flags & NLM_F_REPLACE)) {
/* Only change unicasts */
if (!(is_multicast_ether_addr(f->eth_addr) ||
is_zero_ether_addr(f->eth_addr))) {
notify |= vxlan_fdb_replace(f, ip, port, vni,
26a2: e8 f9 fd ff ff callq 24a0 <vxlan_fdb_append>
ifindex);
} else
return -EOPNOTSUPP;
}
if ((flags & NLM_F_APPEND) &&
26a7: 85 c0 test %eax,%eax
26a9: 78 35 js 26e0 <vxlan_fdb_create+0x150>
26ab: 41 09 c7 or %eax,%r15d
26ae: 31 c0 xor %eax,%eax
26b0: 45 85 ff test %r15d,%r15d
26b3: 74 2b je 26e0 <vxlan_fdb_create+0x150>
(is_multicast_ether_addr(f->eth_addr) ||
26b5: 48 8b 55 c8 mov -0x38(%rbp),%rdx
26b9: 48 85 d2 test %rdx,%rdx
is_zero_ether_addr(f->eth_addr))) {
int rc = vxlan_fdb_append(f, ip, port, vni, ifindex,
26bc: 0f 84 9a 01 00 00 je 285c <vxlan_fdb_create+0x2cc>
26c2: b9 1c 00 00 00 mov $0x1c,%ecx
26c7: 48 89 de mov %rbx,%rsi
26ca: 4c 89 e7 mov %r12,%rdi
26cd: e8 6e f6 ff ff callq 1d40 <vxlan_fdb_notify>
26d2: 31 c0 xor %eax,%eax
26d4: eb 0a jmp 26e0 <vxlan_fdb_create+0x150>
26d6: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
&rd);
if (rc < 0)
return rc;
notify |= rc;
26db: b8 ef ff ff ff mov $0xffffffef,%eax
++vxlan->addrcnt;
hlist_add_head_rcu(&f->hlist,
vxlan_fdb_head(vxlan, mac));
}
if (notify) {
26e0: 48 8b 4d d0 mov -0x30(%rbp),%rcx
26e4: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
26eb: 00 00
if (rd == NULL)
26ed: 0f 85 01 02 00 00 jne 28f4 <vxlan_fdb_create+0x364>
rd = first_remote_rtnl(f);
vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH);
26f3: 48 83 c4 20 add $0x20,%rsp
26f7: 5b pop %rbx
26f8: 41 5c pop %r12
26fa: 41 5d pop %r13
26fc: 41 5e pop %r14
26fe: 41 5f pop %r15
2700: 5d pop %rbp
2701: c3 retq
}
return 0;
2702: 49 8b 74 24 30 mov 0x30(%r12),%rsi
2707: 4c 89 f9 mov %r15,%rcx
270a: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
}
2711: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
2718: e8 00 00 00 00 callq 271d <vxlan_fdb_create+0x18d>
271d: b8 ef ff ff ff mov $0xffffffef,%eax
2722: eb bc jmp 26e0 <vxlan_fdb_create+0x150>
2724: 41 f7 c5 00 04 00 00 test $0x400,%r13d
272b: 0f 84 a5 01 00 00 je 28d6 <vxlan_fdb_create+0x346>
2731: 41 8b 84 24 58 01 00 mov 0x158(%r12),%eax
2738: 00
int notify = 0;
f = __vxlan_find_mac(vxlan, mac);
if (f) {
if (flags & NLM_F_EXCL) {
netdev_dbg(vxlan->dev,
2739: 85 c0 test %eax,%eax
273b: 74 0e je 274b <vxlan_fdb_create+0x1bb>
273d: 41 3b 84 24 ec 00 00 cmp 0xec(%r12),%eax
2744: 00
2745: 0f 86 95 01 00 00 jbe 28e0 <vxlan_fdb_create+0x350>
274b: 41 81 e5 00 01 00 00 and $0x100,%r13d
"lost race to create %pM\n", mac);
return -EEXIST;
2752: 74 18 je 276c <vxlan_fdb_create+0x1dc>
if (rc < 0)
return rc;
notify |= rc;
}
} else {
if (!(flags & NLM_F_CREATE))
2754: 41 8b 07 mov (%r15),%eax
2757: a8 01 test $0x1,%al
2759: 0f 85 f3 00 00 00 jne 2852 <vxlan_fdb_create+0x2c2>
275f: 41 0f b7 57 04 movzwl 0x4(%r15),%edx
return -ENOENT;
if (vxlan->cfg.addrmax &&
2764: 09 c2 or %eax,%edx
2766: 0f 84 e6 00 00 00 je 2852 <vxlan_fdb_create+0x2c2>
276c: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
2771: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # 2778 <vxlan_fdb_create+0x1e8>
2778: ba 50 00 00 00 mov $0x50,%edx
vxlan->addrcnt >= vxlan->cfg.addrmax)
return -ENOSPC;
/* Disallow replace to add a multicast entry */
if ((flags & NLM_F_REPLACE) &&
277d: be 20 00 08 02 mov $0x2080020,%esi
2782: e8 00 00 00 00 callq 2787 <vxlan_fdb_create+0x1f7>
2787: 48 85 c0 test %rax,%rax
278a: 48 89 c3 mov %rax,%rbx
278d: 0f 84 57 01 00 00 je 28ea <vxlan_fdb_create+0x35a>
(is_multicast_ether_addr(mac) || is_zero_ether_addr(mac)))
2793: 0f b7 45 c4 movzwl -0x3c(%rbp),%eax
2797: 0f b7 55 c0 movzwl -0x40(%rbp),%edx
279b: 4c 8d 4d c8 lea -0x38(%rbp),%r9
279f: 44 8b 45 18 mov 0x18(%rbp),%r8d
27a3: 8b 4d 10 mov 0x10(%rbp),%ecx
27a6: 48 89 df mov %rbx,%rdi
27a9: 48 8b 75 b8 mov -0x48(%rbp),%rsi
27ad: 44 88 73 48 mov %r14b,0x48(%rbx)
27b1: 66 89 43 46 mov %ax,0x46(%rbx)
27b5: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 27bc <vxlan_fdb_create+0x22c>
27bc: 48 89 43 28 mov %rax,0x28(%rbx)
return -EOPNOTSUPP;
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
f = kmalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
27c0: 48 89 43 20 mov %rax,0x20(%rbx)
return -ENOMEM;
notify = 1;
f->state = state;
27c4: 48 8d 43 30 lea 0x30(%rbx),%rax
f->flags = ndm_flags;
f->updated = f->used = jiffies;
INIT_LIST_HEAD(&f->remotes);
memcpy(f->eth_addr, mac, ETH_ALEN);
vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
27c8: 48 89 43 30 mov %rax,0x30(%rbx)
27cc: 48 89 43 38 mov %rax,0x38(%rbx)
27d0: 41 8b 07 mov (%r15),%eax
27d3: 89 43 40 mov %eax,0x40(%rbx)
27d6: 41 0f b7 47 04 movzwl 0x4(%r15),%eax
27db: 66 89 43 44 mov %ax,0x44(%rbx)
if (!f)
return -ENOMEM;
notify = 1;
f->state = state;
f->flags = ndm_flags;
27df: e8 bc fc ff ff callq 24a0 <vxlan_fdb_append>
f = kmalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
return -ENOMEM;
notify = 1;
f->state = state;
27e4: 41 83 84 24 ec 00 00 addl $0x1,0xec(%r12)
27eb: 00 01
f->flags = ndm_flags;
f->updated = f->used = jiffies;
27ed: 48 ba eb 83 b5 80 46 movabs $0x61c8864680b583eb,%rdx
27f4: 86 c8 61
INIT_LIST_HEAD(&f->remotes);
27f7: 49 8b 07 mov (%r15),%rax
27fa: 48 c1 e0 10 shl $0x10,%rax
struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
WRITE_ONCE(list->next, list);
list->prev = list;
27fe: 48 0f af c2 imul %rdx,%rax
memcpy(f->eth_addr, mac, ETH_ALEN);
2802: 48 c1 e8 38 shr $0x38,%rax
2806: 48 83 c0 2c add $0x2c,%rax
280a: 49 8d 14 c4 lea (%r12,%rax,8),%rdx
280e: 49 8b 04 c4 mov (%r12,%rax,8),%rax
vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
2812: 48 89 53 08 mov %rdx,0x8(%rbx)
++vxlan->addrcnt;
2816: 48 89 03 mov %rax,(%rbx)
2819: 48 85 c0 test %rax,%rax
281c: 48 89 1a mov %rbx,(%rdx)
#endif
static __always_inline u32 hash_64_generic(u64 val, unsigned int bits)
{
#if BITS_PER_LONG == 64
/* 64x64-bit multiply is efficient on all 64-bit processors */
return val * GOLDEN_RATIO_64 >> (64 - bits);
281f: 0f 84 90 fe ff ff je 26b5 <vxlan_fdb_create+0x125>
2825: 48 89 58 08 mov %rbx,0x8(%rax)
2829: e9 87 fe ff ff jmpq 26b5 <vxlan_fdb_create+0x125>
282e: 49 8b 74 24 30 mov 0x30(%r12),%rsi
/* Hash chain to use given mac address */
static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan,
const u8 *mac)
{
return &vxlan->fdb_head[eth_hash(mac)];
2833: 4c 8b 45 b8 mov -0x48(%rbp),%r8
2837: 4c 89 f9 mov %r15,%rcx
283a: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
* list-traversal primitive must be guarded by rcu_read_lock().
*/
static inline void hlist_add_head_rcu(struct hlist_node *n,
struct hlist_head *h)
{
struct hlist_node *first = h->first;
2841: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
n->next = first;
2848: e8 00 00 00 00 callq 284d <vxlan_fdb_create+0x2bd>
284d: e9 1f ff ff ff jmpq 2771 <vxlan_fdb_create+0x1e1>
n->pprev = &h->first;
rcu_assign_pointer(hlist_first_rcu(h), n);
if (first)
2852: b8 a1 ff ff ff mov $0xffffffa1,%eax
first->pprev = &n->next;
2857: e9 84 fe ff ff jmpq 26e0 <vxlan_fdb_create+0x150>
285c: 48 8b 43 30 mov 0x30(%rbx),%rax
/* Disallow replace to add a multicast entry */
if ((flags & NLM_F_REPLACE) &&
(is_multicast_ether_addr(mac) || is_zero_ether_addr(mac)))
return -EOPNOTSUPP;
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
2860: 48 8d 50 d8 lea -0x28(%rax),%rdx
2864: 48 89 55 c8 mov %rdx,-0x38(%rbp)
2868: e9 55 fe ff ff jmpq 26c2 <vxlan_fdb_create+0x132>
286d: 48 8b 43 30 mov 0x30(%rbx),%rax
2871: 48 8d 4b 30 lea 0x30(%rbx),%rcx
2875: 48 39 c1 cmp %rax,%rcx
2878: 0f 84 f3 fd ff ff je 2671 <vxlan_fdb_create+0xe1>
287e: 48 8b 43 30 mov 0x30(%rbx),%rax
if (!(is_multicast_ether_addr(f->eth_addr) ||
is_zero_ether_addr(f->eth_addr))) {
notify |= vxlan_fdb_replace(f, ip, port, vni,
ifindex);
} else
return -EOPNOTSUPP;
2882: 48 83 f8 28 cmp $0x28,%rax
2886: 0f 84 e5 fd ff ff je 2671 <vxlan_fdb_create+0xe1>
return list_entry_rcu(fdb->remotes.next, struct vxlan_rdst, list);
}
static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
{
return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
288c: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 2893 <vxlan_fdb_create+0x303>
2893: 48 8b 7d b8 mov -0x48(%rbp),%rdi
vxlan_fdb_head(vxlan, mac));
}
if (notify) {
if (rd == NULL)
rd = first_remote_rtnl(f);
2897: 0f b7 75 c0 movzwl -0x40(%rbp),%esi
289b: 48 89 50 28 mov %rdx,0x28(%rax)
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
289f: 48 8b 17 mov (%rdi),%rdx
rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
if (rd)
return 0;
rd = list_first_entry_or_null(&f->remotes, struct vxlan_rdst, list);
28a2: 48 89 50 d8 mov %rdx,-0x28(%rax)
28a6: 48 8b 57 08 mov 0x8(%rdi),%rdx
28aa: 48 89 50 e0 mov %rdx,-0x20(%rax)
28ae: 48 8b 57 10 mov 0x10(%rdi),%rdx
if (!rd)
28b2: 48 89 50 e8 mov %rdx,-0x18(%rax)
28b6: 8b 57 18 mov 0x18(%rdi),%edx
28b9: 66 89 70 f4 mov %si,-0xc(%rax)
* This do not free the cached dst to avoid races and contentions.
* the dst will be freed on later cache lookup.
*/
static inline void dst_cache_reset(struct dst_cache *dst_cache)
{
dst_cache->reset_ts = jiffies;
28bd: 8b 7d 10 mov 0x10(%rbp),%edi
28c0: 8b 75 18 mov 0x18(%rbp),%esi
return 0;
dst_cache_reset(&rd->dst_cache);
rd->remote_ip = *ip;
28c3: 89 50 f0 mov %edx,-0x10(%rax)
28c6: ba 01 00 00 00 mov $0x1,%edx
28cb: 89 78 f8 mov %edi,-0x8(%rax)
28ce: 89 70 fc mov %esi,-0x4(%rax)
28d1: e9 9b fd ff ff jmpq 2671 <vxlan_fdb_create+0xe1>
28d6: b8 fe ff ff ff mov $0xfffffffe,%eax
28db: e9 00 fe ff ff jmpq 26e0 <vxlan_fdb_create+0x150>
28e0: b8 e4 ff ff ff mov $0xffffffe4,%eax
28e5: e9 f6 fd ff ff jmpq 26e0 <vxlan_fdb_create+0x150>
rd->remote_port = port;
28ea: b8 f4 ff ff ff mov $0xfffffff4,%eax
rd->remote_vni = vni;
28ef: e9 ec fd ff ff jmpq 26e0 <vxlan_fdb_create+0x150>
rd = list_first_entry_or_null(&f->remotes, struct vxlan_rdst, list);
if (!rd)
return 0;
dst_cache_reset(&rd->dst_cache);
rd->remote_ip = *ip;
28f4: e8 00 00 00 00 callq 28f9 <vxlan_fdb_create+0x369>
rd->remote_port = port;
rd->remote_vni = vni;
rd->remote_ifindex = ifindex;
return 1;
28f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000002900 <vxlan_dev_configure>:
dst_cache_reset(&rd->dst_cache);
rd->remote_ip = *ip;
rd->remote_port = port;
rd->remote_vni = vni;
rd->remote_ifindex = ifindex;
2900: e8 00 00 00 00 callq 2905 <vxlan_dev_configure+0x5>
2905: 55 push %rbp
return rc;
notify |= rc;
}
} else {
if (!(flags & NLM_F_CREATE))
return -ENOENT;
2906: 48 89 e5 mov %rsp,%rbp
2909: 41 57 push %r15
290b: 41 56 push %r14
290d: 41 55 push %r13
290f: 41 54 push %r12
if (vxlan->cfg.addrmax &&
vxlan->addrcnt >= vxlan->cfg.addrmax)
return -ENOSPC;
2911: 49 89 d4 mov %rdx,%r12
2914: 53 push %rbx
2915: 48 89 f3 mov %rsi,%rbx
2918: 4c 8d ae 40 08 00 00 lea 0x840(%rsi),%r13
return -EOPNOTSUPP;
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
f = kmalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
return -ENOMEM;
291f: 48 83 ec 20 sub $0x20,%rsp
2923: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 2929 <vxlan_dev_configure+0x29>
rd = first_remote_rtnl(f);
vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH);
}
return 0;
}
2929: 48 8b 97 88 14 00 00 mov 0x1488(%rdi),%rdx
return ret;
}
static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
struct vxlan_config *conf)
{
2930: 0f b7 8e 7c 09 00 00 movzwl 0x97c(%rsi),%ecx
2937: 83 e8 01 sub $0x1,%eax
293a: 48 98 cltq
293c: 4c 8b 74 c2 18 mov 0x18(%rdx,%rax,8),%r14
2941: 41 8b 44 24 50 mov 0x50(%r12),%eax
2946: f6 c4 40 test $0x40,%ah
2949: 0f 84 82 02 00 00 je 2bd1 <vxlan_dev_configure+0x2d1>
294f: 25 1f be ff ff and $0xffffbe1f,%eax
2954: 3d 00 20 00 00 cmp $0x2000,%eax
2959: 0f 85 0a 05 00 00 jne 2e69 <vxlan_dev_configure+0x569>
295f: 41 b9 fe ff ff ff mov $0xfffffffe,%r9d
struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
struct vxlan_rdst *dst = &vxlan->default_dst;
unsigned short needed_headroom = ETH_HLEN;
int err;
bool use_ipv6 = false;
__be16 default_port = vxlan->cfg.dst_port;
2965: 45 31 d2 xor %r10d,%r10d
2968: 48 c7 86 30 02 00 00 movq $0x0,0x230(%rsi)
296f: 00 00 00 00
struct net_device *lowerdev = NULL;
if (conf->flags & VXLAN_F_GPE) {
2973: 66 44 89 8e 4c 02 00 mov %r9w,0x24c(%rsi)
297a: 00
297b: 66 44 89 96 4e 02 00 mov %r10w,0x24e(%rsi)
2982: 00
/* For now, allow GPE only together with COLLECT_METADATA.
* This can be relaxed later; in such case, the other side
* of the PtP link will have to be provided.
*/
if ((conf->flags & ~VXLAN_F_ALLOWED_GPE) ||
2983: c6 86 75 02 00 00 00 movb $0x0,0x275(%rsi)
298a: c7 86 38 02 00 00 90 movl $0x1090,0x238(%rsi)
2991: 10 00 00
}
static void vxlan_raw_setup(struct net_device *dev)
{
dev->header_ops = NULL;
dev->type = ARPHRD_NONE;
2994: 48 c7 86 10 02 00 00 movq $0x0,0x210(%rsi)
299b: 00 00 00 00
dev->netdev_ops = &vxlan_netdev_ether_ops;
}
static void vxlan_raw_setup(struct net_device *dev)
{
dev->header_ops = NULL;
299f: 48 89 bb 78 08 00 00 mov %rdi,0x878(%rbx)
dev->type = ARPHRD_NONE;
29a6: 41 8b 44 24 38 mov 0x38(%r12),%eax
dev->hard_header_len = 0;
29ab: 4c 8d bb 80 08 00 00 lea 0x880(%rbx),%r15
29b2: 89 83 a0 08 00 00 mov %eax,0x8a0(%rbx)
dev->addr_len = 0;
29b8: 49 8b 04 24 mov (%r12),%rax
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
29bc: 48 89 83 80 08 00 00 mov %rax,0x880(%rbx)
29c3: 49 8b 44 24 08 mov 0x8(%r12),%rax
dev->netdev_ops = &vxlan_netdev_raw_ops;
29c8: 49 89 47 08 mov %rax,0x8(%r15)
29cc: 49 8b 44 24 10 mov 0x10(%r12),%rax
vxlan_raw_setup(dev);
} else {
vxlan_ether_setup(dev);
}
vxlan->net = src_net;
29d1: 49 89 47 10 mov %rax,0x10(%r15)
29d5: 41 8b 44 24 18 mov 0x18(%r12),%eax
dst->remote_vni = conf->vni;
29da: 41 89 47 18 mov %eax,0x18(%r15)
memcpy(&dst->remote_ip, &conf->remote_ip, sizeof(conf->remote_ip));
29de: 0f b7 83 80 08 00 00 movzwl 0x880(%rbx),%eax
vxlan_ether_setup(dev);
}
vxlan->net = src_net;
dst->remote_vni = conf->vni;
29e5: 66 85 c0 test %ax,%ax
memcpy(&dst->remote_ip, &conf->remote_ip, sizeof(conf->remote_ip));
29e8: 0f 85 b1 02 00 00 jne 2c9f <vxlan_dev_configure+0x39f>
29ee: 41 b8 02 00 00 00 mov $0x2,%r8d
29f4: 66 44 89 83 80 08 00 mov %r8w,0x880(%rbx)
29fb: 00
29fc: 66 83 bb 54 09 00 00 cmpw $0xa,0x954(%rbx)
2a03: 0a
2a04: 0f 84 e2 02 00 00 je 2cec <vxlan_dev_configure+0x3ec>
2a0a: 41 8b 44 24 4c mov 0x4c(%r12),%eax
/* Unless IPv6 is explicitly requested, assume IPv4 */
if (!dst->remote_ip.sa.sa_family)
2a0f: 85 c0 test %eax,%eax
2a11: 0f 85 26 04 00 00 jne 2e3d <vxlan_dev_configure+0x53d>
2a17: 41 8b 74 24 3c mov 0x3c(%r12),%esi
2a1c: 85 f6 test %esi,%esi
dst->remote_ip.sa.sa_family = AF_INET;
2a1e: 0f 85 e6 02 00 00 jne 2d0a <vxlan_dev_configure+0x40a>
2a24: 31 ff xor %edi,%edi
2a26: 8b 83 84 08 00 00 mov 0x884(%rbx),%eax
if (dst->remote_ip.sa.sa_family == AF_INET6 ||
2a2c: 25 f0 00 00 00 and $0xf0,%eax
2a31: 3d e0 00 00 00 cmp $0xe0,%eax
2a36: 0f 94 c0 sete %al
2a39: 84 c0 test %al,%al
return -EPFNOSUPPORT;
use_ipv6 = true;
vxlan->flags |= VXLAN_F_IPV6;
}
if (conf->label && !use_ipv6) {
2a3b: 0f 85 12 04 00 00 jne 2e53 <vxlan_dev_configure+0x553>
2a41: 41 8b 74 24 40 mov 0x40(%r12),%esi
2a46: 41 b8 0e 00 00 00 mov $0xe,%r8d
pr_info("label only supported in use with IPv6\n");
return -EINVAL;
}
if (conf->remote_ifindex) {
2a4c: 85 f6 test %esi,%esi
2a4e: 0f 85 c9 03 00 00 jne 2e1d <vxlan_dev_configure+0x51d>
struct vxlan_net *vn = net_generic(src_net, vxlan_net_id);
struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
struct vxlan_rdst *dst = &vxlan->default_dst;
unsigned short needed_headroom = ETH_HLEN;
int err;
bool use_ipv6 = false;
2a54: 40 84 ff test %dil,%dil
static inline bool vxlan_addr_multicast(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
return ipv6_addr_is_multicast(&ipa->sin6.sin6_addr);
else
return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
2a57: 75 0c jne 2a65 <vxlan_dev_configure+0x165>
2a59: 41 f6 44 24 51 20 testb $0x20,0x51(%r12)
2a5f: 41 8d 40 32 lea 0x32(%r8),%eax
2a63: 74 04 je 2a69 <vxlan_dev_configure+0x169>
2a65: 41 8d 40 46 lea 0x46(%r8),%eax
if (!conf->mtu)
dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
needed_headroom = lowerdev->hard_header_len;
} else if (vxlan_addr_multicast(&dst->remote_ip)) {
2a69: 66 89 83 50 02 00 00 mov %ax,0x250(%rbx)
2a70: 49 8b 14 24 mov (%r12),%rdx
pr_info("multicast destination requires interface to be specified\n");
return -EINVAL;
}
if (conf->mtu) {
2a74: 48 89 93 38 09 00 00 mov %rdx,0x938(%rbx)
struct vxlan_config *conf)
{
struct vxlan_net *vn = net_generic(src_net, vxlan_net_id);
struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
struct vxlan_rdst *dst = &vxlan->default_dst;
unsigned short needed_headroom = ETH_HLEN;
2a7b: 49 8b 54 24 08 mov 0x8(%r12),%rdx
} else if (vxlan_addr_multicast(&dst->remote_ip)) {
pr_info("multicast destination requires interface to be specified\n");
return -EINVAL;
}
if (conf->mtu) {
2a80: 48 89 93 40 09 00 00 mov %rdx,0x940(%rbx)
err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
if (err)
return err;
}
if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
2a87: 49 8b 54 24 10 mov 0x10(%r12),%rdx
2a8c: 48 89 93 48 09 00 00 mov %rdx,0x948(%rbx)
2a93: 49 8b 54 24 18 mov 0x18(%r12),%rdx
needed_headroom += VXLAN6_HEADROOM;
2a98: 48 89 93 50 09 00 00 mov %rdx,0x950(%rbx)
else
needed_headroom += VXLAN_HEADROOM;
dev->needed_headroom = needed_headroom;
2a9f: 49 8b 54 24 20 mov 0x20(%r12),%rdx
memcpy(&vxlan->cfg, conf, sizeof(*conf));
2aa4: 48 89 93 58 09 00 00 mov %rdx,0x958(%rbx)
2aab: 49 8b 54 24 28 mov 0x28(%r12),%rdx
2ab0: 48 89 93 60 09 00 00 mov %rdx,0x960(%rbx)
2ab7: 49 8b 54 24 30 mov 0x30(%r12),%rdx
2abc: 48 89 93 68 09 00 00 mov %rdx,0x968(%rbx)
2ac3: 49 8b 54 24 38 mov 0x38(%r12),%rdx
2ac8: 48 89 93 70 09 00 00 mov %rdx,0x970(%rbx)
2acf: 49 8b 54 24 40 mov 0x40(%r12),%rdx
2ad4: 48 89 93 78 09 00 00 mov %rdx,0x978(%rbx)
2adb: 49 8b 54 24 48 mov 0x48(%r12),%rdx
2ae0: 66 83 bb 7c 09 00 00 cmpw $0x0,0x97c(%rbx)
2ae7: 00
2ae8: 48 89 93 80 09 00 00 mov %rdx,0x980(%rbx)
2aef: 49 8b 54 24 50 mov 0x50(%r12),%rdx
2af4: 48 89 93 88 09 00 00 mov %rdx,0x988(%rbx)
2afb: 49 8b 54 24 58 mov 0x58(%r12),%rdx
2b00: 48 89 93 90 09 00 00 mov %rdx,0x990(%rbx)
2b07: 49 8b 54 24 60 mov 0x60(%r12),%rdx
2b0c: 48 89 93 98 09 00 00 mov %rdx,0x998(%rbx)
if (!vxlan->cfg.dst_port) {
2b13: 75 15 jne 2b2a <vxlan_dev_configure+0x22a>
2b15: 41 f6 44 24 51 40 testb $0x40,0x51(%r12)
needed_headroom += VXLAN6_HEADROOM;
else
needed_headroom += VXLAN_HEADROOM;
dev->needed_headroom = needed_headroom;
memcpy(&vxlan->cfg, conf, sizeof(*conf));
2b1b: b8 b6 12 00 00 mov $0x12b6,%eax
2b20: 0f 45 c8 cmovne %eax,%ecx
2b23: 66 89 8b 7c 09 00 00 mov %cx,0x97c(%rbx)
2b2a: 44 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%r8d
2b31: 45 0b 44 24 50 or 0x50(%r12),%r8d
2b36: 48 83 bb 90 09 00 00 cmpq $0x0,0x990(%rbx)
2b3d: 00
2b3e: 44 89 83 d8 08 00 00 mov %r8d,0x8d8(%rbx)
if (!vxlan->cfg.dst_port) {
if (conf->flags & VXLAN_F_GPE)
vxlan->cfg.dst_port = 4790; /* IANA assigned VXLAN-GPE port */
2b45: 75 0b jne 2b52 <vxlan_dev_configure+0x252>
2b47: 48 c7 83 90 09 00 00 movq $0x12c,0x990(%rbx)
2b4e: 2c 01 00 00
2b52: 49 8b 16 mov (%r14),%rdx
2b55: 49 39 d6 cmp %rdx,%r14
2b58: 48 8d 42 f0 lea -0x10(%rdx),%rax
else
vxlan->cfg.dst_port = default_port;
}
vxlan->flags |= conf->flags;
2b5c: 0f 84 91 00 00 00 je 2bf3 <vxlan_dev_configure+0x2f3>
2b62: 41 8b 74 24 38 mov 0x38(%r12),%esi
if (!vxlan->cfg.age_interval)
2b67: eb 0d jmp 2b76 <vxlan_dev_configure+0x276>
2b69: 48 8b 48 10 mov 0x10(%rax),%rcx
2b6d: 49 39 ce cmp %rcx,%r14
if (conf->flags & VXLAN_F_GPE)
vxlan->cfg.dst_port = 4790; /* IANA assigned VXLAN-GPE port */
else
vxlan->cfg.dst_port = default_port;
}
vxlan->flags |= conf->flags;
2b70: 48 8d 41 f0 lea -0x10(%rcx),%rax
2b74: 74 7d je 2bf3 <vxlan_dev_configure+0x2f3>
if (!vxlan->cfg.age_interval)
2b76: 39 b0 30 01 00 00 cmp %esi,0x130(%rax)
vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
2b7c: 75 eb jne 2b69 <vxlan_dev_configure+0x269>
2b7e: 66 83 78 40 0a cmpw $0xa,0x40(%rax)
list_for_each_entry(tmp, &vn->vxlan_list, next) {
2b83: ba 01 00 00 00 mov $0x1,%edx
2b88: 74 0d je 2b97 <vxlan_dev_configure+0x297>
2b8a: 31 d2 xor %edx,%edx
2b8c: 66 83 b8 14 01 00 00 cmpw $0xa,0x114(%rax)
2b93: 0a
2b94: 0f 94 c2 sete %dl
2b97: 39 fa cmp %edi,%edx
2b99: 75 ce jne 2b69 <vxlan_dev_configure+0x269>
2b9b: 0f b7 93 7c 09 00 00 movzwl 0x97c(%rbx),%edx
2ba2: 66 39 90 3c 01 00 00 cmp %dx,0x13c(%rax)
if (tmp->cfg.vni == conf->vni &&
2ba9: 75 be jne 2b69 <vxlan_dev_configure+0x269>
2bab: 8b 90 98 00 00 00 mov 0x98(%rax),%edx
(tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
2bb1: 44 31 c2 xor %r8d,%edx
2bb4: 80 e6 7d and $0x7d,%dh
2bb7: 75 b0 jne 2b69 <vxlan_dev_configure+0x269>
2bb9: 0f ce bswap %esi
2bbb: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
2bc2: e8 00 00 00 00 callq 2bc7 <vxlan_dev_configure+0x2c7>
if (!vxlan->cfg.age_interval)
vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
list_for_each_entry(tmp, &vn->vxlan_list, next) {
if (tmp->cfg.vni == conf->vni &&
2bc7: b8 ef ff ff ff mov $0xffffffef,%eax
(tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
2bcc: e9 bf 00 00 00 jmpq 2c90 <vxlan_dev_configure+0x390>
2bd1: 8b 86 3c 02 00 00 mov 0x23c(%rsi),%eax
2bd7: 48 c7 86 10 02 00 00 movq $0x0,0x210(%rsi)
2bde: 00 00 00 00
tmp->cfg.dst_port == vxlan->cfg.dst_port &&
2be2: 80 e4 f7 and $0xf7,%ah
2be5: 80 cc 80 or $0x80,%ah
2be8: 89 86 3c 02 00 00 mov %eax,0x23c(%rsi)
(tmp->flags & VXLAN_F_RCV_FLAGS) ==
(vxlan->flags & VXLAN_F_RCV_FLAGS)) {
pr_info("duplicate VNI %u\n", be32_to_cpu(conf->vni));
2bee: e9 ac fd ff ff jmpq 299f <vxlan_dev_configure+0x9f>
2bf3: 66 83 bb 80 08 00 00 cmpw $0xa,0x880(%rbx)
2bfa: 0a
return -EEXIST;
2bfb: 48 c7 83 18 02 00 00 movq $0x0,0x218(%rbx)
2c02: 00 00 00 00
}
static void vxlan_ether_setup(struct net_device *dev)
{
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
2c06: 0f 84 ca 00 00 00 je 2cd6 <vxlan_dev_configure+0x3d6>
dev->netdev_ops = &vxlan_netdev_ether_ops;
2c0c: 8b 93 84 08 00 00 mov 0x884(%rbx),%edx
}
static void vxlan_ether_setup(struct net_device *dev)
{
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
2c12: 85 d2 test %edx,%edx
2c14: 0f 94 c0 sete %al
2c17: 84 c0 test %al,%al
2c19: 75 44 jne 2c5f <vxlan_dev_configure+0x35f>
2c1b: 8b 83 a4 08 00 00 mov 0x8a4(%rbx),%eax
2c21: 44 0f b7 8b 7c 09 00 movzwl 0x97c(%rbx),%r9d
2c28: 00
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
2c29: 41 b8 00 06 00 00 mov $0x600,%r8d
pr_info("duplicate VNI %u\n", be32_to_cpu(conf->vni));
return -EEXIST;
}
}
dev->ethtool_ops = &vxlan_ethtool_ops;
2c2f: c7 44 24 10 02 00 00 movl $0x2,0x10(%rsp)
2c36: 00
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
2c37: b9 82 00 00 00 mov $0x82,%ecx
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
2c3c: 4c 89 fa mov %r15,%rdx
2c3f: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
2c46: 4c 89 ef mov %r13,%rdi
}
dev->ethtool_ops = &vxlan_ethtool_ops;
/* create an fdb entry for a valid default destination */
if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) {
2c49: 89 44 24 08 mov %eax,0x8(%rsp)
err = vxlan_fdb_create(vxlan, all_zeros_mac,
2c4d: 8b 83 a0 08 00 00 mov 0x8a0(%rbx),%eax
2c53: 89 04 24 mov %eax,(%rsp)
2c56: e8 35 f9 ff ff callq 2590 <vxlan_fdb_create>
2c5b: 85 c0 test %eax,%eax
2c5d: 75 31 jne 2c90 <vxlan_dev_configure+0x390>
2c5f: 48 89 df mov %rbx,%rdi
2c62: e8 00 00 00 00 callq 2c67 <vxlan_dev_configure+0x367>
2c67: 85 c0 test %eax,%eax
2c69: 0f 85 91 01 00 00 jne 2e00 <vxlan_dev_configure+0x500>
2c6f: 49 8b 16 mov (%r14),%rdx
2c72: 48 8d 83 50 08 00 00 lea 0x850(%rbx),%rax
2c79: 48 89 42 08 mov %rax,0x8(%rdx)
2c7d: 48 89 93 50 08 00 00 mov %rdx,0x850(%rbx)
2c84: 4c 89 b3 58 08 00 00 mov %r14,0x858(%rbx)
NLM_F_EXCL|NLM_F_CREATE,
vxlan->cfg.dst_port,
vxlan->default_dst.remote_vni,
vxlan->default_dst.remote_ifindex,
NTF_SELF);
if (err)
2c8b: 49 89 06 mov %rax,(%r14)
2c8e: 31 c0 xor %eax,%eax
return err;
}
err = register_netdevice(dev);
2c90: 48 83 c4 20 add $0x20,%rsp
2c94: 5b pop %rbx
2c95: 41 5c pop %r12
if (err) {
2c97: 41 5d pop %r13
2c99: 41 5e pop %r14
2c9b: 41 5f pop %r15
2c9d: 5d pop %rbp
2c9e: c3 retq
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
2c9f: 66 83 f8 0a cmp $0xa,%ax
vxlan_fdb_delete_default(vxlan);
return err;
}
list_add(&vxlan->next, &vn->vxlan_list);
2ca3: 0f 85 53 fd ff ff jne 29fc <vxlan_dev_configure+0xfc>
#ifndef CONFIG_DEBUG_LIST
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
2ca9: 83 8b d8 08 00 00 20 orl $0x20,0x8d8(%rbx)
new->next = next;
2cb0: 41 8b 74 24 3c mov 0x3c(%r12),%esi
new->prev = prev;
2cb5: 85 f6 test %esi,%esi
2cb7: 0f 85 dc 00 00 00 jne 2d99 <vxlan_dev_configure+0x499>
{
switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
2cbd: 0f b6 83 88 08 00 00 movzbl 0x888(%rbx),%eax
return 0;
}
2cc4: bf 01 00 00 00 mov $0x1,%edi
2cc9: 3d ff 00 00 00 cmp $0xff,%eax
2cce: 0f 94 c0 sete %al
/* Unless IPv6 is explicitly requested, assume IPv4 */
if (!dst->remote_ip.sa.sa_family)
dst->remote_ip.sa.sa_family = AF_INET;
if (dst->remote_ip.sa.sa_family == AF_INET6 ||
2cd1: e9 63 fd ff ff jmpq 2a39 <vxlan_dev_configure+0x139>
2cd6: 48 8b 83 88 08 00 00 mov 0x888(%rbx),%rax
vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
use_ipv6 = true;
vxlan->flags |= VXLAN_F_IPV6;
2cdd: 48 0b 83 90 08 00 00 or 0x890(%rbx),%rax
if (conf->label && !use_ipv6) {
pr_info("label only supported in use with IPv6\n");
return -EINVAL;
}
if (conf->remote_ifindex) {
2ce4: 0f 94 c0 sete %al
2ce7: e9 2b ff ff ff jmpq 2c17 <vxlan_dev_configure+0x317>
2cec: 83 8b d8 08 00 00 20 orl $0x20,0x8d8(%rbx)
return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
}
static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
{
return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
2cf3: 41 8b 74 24 3c mov 0x3c(%r12),%esi
if (dst->remote_ip.sa.sa_family == AF_INET6 ||
vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
use_ipv6 = true;
2cf8: 85 f6 test %esi,%esi
2cfa: 0f 85 99 00 00 00 jne 2d99 <vxlan_dev_configure+0x499>
2d00: bf 01 00 00 00 mov $0x1,%edi
2d05: e9 1c fd ff ff jmpq 2a26 <vxlan_dev_configure+0x126>
static inline bool ipv6_addr_any(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul = (const unsigned long *)a;
return (ul[0] | ul[1]) == 0UL;
2d0a: 89 4d d4 mov %ecx,-0x2c(%rbp)
2d0d: e8 00 00 00 00 callq 2d12 <vxlan_dev_configure+0x412>
2d12: 41 8b 74 24 3c mov 0x3c(%r12),%esi
2d17: 48 85 c0 test %rax,%rax
2d1a: 8b 4d d4 mov -0x2c(%rbp),%ecx
vxlan->flags |= VXLAN_F_IPV6;
2d1d: 89 b3 a4 08 00 00 mov %esi,0x8a4(%rbx)
if (conf->label && !use_ipv6) {
pr_info("label only supported in use with IPv6\n");
return -EINVAL;
}
if (conf->remote_ifindex) {
2d23: 0f 84 fe 00 00 00 je 2e27 <vxlan_dev_configure+0x527>
2d29: 41 8b 54 24 40 mov 0x40(%r12),%edx
2d2e: 31 ff xor %edi,%edi
if (dst->remote_ip.sa.sa_family == AF_INET6 ||
vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
use_ipv6 = true;
2d30: 85 d2 test %edx,%edx
2d32: 0f 85 b9 00 00 00 jne 2df1 <vxlan_dev_configure+0x4f1>
2d38: 8b 90 48 02 00 00 mov 0x248(%rax),%edx
pr_info("label only supported in use with IPv6\n");
return -EINVAL;
}
if (conf->remote_ifindex) {
lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
2d3e: 31 ff xor %edi,%edi
2d40: be 32 00 00 00 mov $0x32,%esi
dst->remote_ifindex = conf->remote_ifindex;
2d45: 29 f2 sub %esi,%edx
if (!lowerdev) {
2d47: 89 93 48 02 00 00 mov %edx,0x248(%rbx)
return -EINVAL;
}
if (conf->remote_ifindex) {
lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
dst->remote_ifindex = conf->remote_ifindex;
2d4d: 41 8b 54 24 40 mov 0x40(%r12),%edx
2d52: 44 0f b7 80 4e 02 00 movzwl 0x24e(%rax),%r8d
2d59: 00
return -EPERM;
}
}
#endif
if (!conf->mtu)
2d5a: 85 d2 test %edx,%edx
2d5c: 0f 84 f2 fc ff ff je 2a54 <vxlan_dev_configure+0x154>
2d62: 89 d6 mov %edx,%esi
2d64: 8b 80 48 02 00 00 mov 0x248(%rax),%eax
dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
2d6a: 8d 50 ba lea -0x46(%rax),%edx
2d6d: 83 e8 32 sub $0x32,%eax
2d70: 66 83 bb 80 08 00 00 cmpw $0xa,0x880(%rbx)
2d77: 0a
2d78: 0f 45 d0 cmovne %eax,%edx
2d7b: 83 fe 43 cmp $0x43,%esi
2d7e: b8 ea ff ff ff mov $0xffffffea,%eax
needed_headroom = lowerdev->hard_header_len;
2d83: 0f 8e 07 ff ff ff jle 2c90 <vxlan_dev_configure+0x390>
2d89: 39 f2 cmp %esi,%edx
} else if (vxlan_addr_multicast(&dst->remote_ip)) {
pr_info("multicast destination requires interface to be specified\n");
return -EINVAL;
}
if (conf->mtu) {
2d8b: 0f 4f d6 cmovg %esi,%edx
2d8e: 89 93 48 02 00 00 mov %edx,0x248(%rbx)
struct vxlan_rdst *dst, int new_mtu, bool strict)
{
int max_mtu = IP_MAX_MTU;
if (lowerdev)
max_mtu = lowerdev->mtu;
2d94: e9 bb fc ff ff jmpq 2a54 <vxlan_dev_configure+0x154>
2d99: 89 4d d4 mov %ecx,-0x2c(%rbp)
if (dst->remote_ip.sa.sa_family == AF_INET6)
max_mtu -= VXLAN6_HEADROOM;
2d9c: e8 00 00 00 00 callq 2da1 <vxlan_dev_configure+0x4a1>
2da1: 41 8b 74 24 3c mov 0x3c(%r12),%esi
2da6: 48 85 c0 test %rax,%rax
2da9: 8b 4d d4 mov -0x2c(%rbp),%ecx
else
max_mtu -= VXLAN_HEADROOM;
if (new_mtu < 68)
2dac: 89 b3 a4 08 00 00 mov %esi,0x8a4(%rbx)
return -EINVAL;
2db2: 74 73 je 2e27 <vxlan_dev_configure+0x527>
if (dst->remote_ip.sa.sa_family == AF_INET6)
max_mtu -= VXLAN6_HEADROOM;
else
max_mtu -= VXLAN_HEADROOM;
if (new_mtu < 68)
2db4: 48 8b 90 08 03 00 00 mov 0x308(%rax),%rdx
return -EINVAL;
new_mtu = max_mtu;
}
dev->mtu = new_mtu;
2dbb: 48 85 d2 test %rdx,%rdx
2dbe: 74 0e je 2dce <vxlan_dev_configure+0x4ce>
2dc0: 8b b2 38 02 00 00 mov 0x238(%rdx),%esi
2dc6: 85 f6 test %esi,%esi
2dc8: 0f 85 b1 00 00 00 jne 2e7f <vxlan_dev_configure+0x57f>
pr_info("label only supported in use with IPv6\n");
return -EINVAL;
}
if (conf->remote_ifindex) {
lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
2dce: 41 8b 54 24 40 mov 0x40(%r12),%edx
dst->remote_ifindex = conf->remote_ifindex;
2dd3: bf 01 00 00 00 mov $0x1,%edi
if (!lowerdev) {
2dd8: 85 d2 test %edx,%edx
2dda: 75 15 jne 2df1 <vxlan_dev_configure+0x4f1>
return -EINVAL;
}
if (conf->remote_ifindex) {
lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
dst->remote_ifindex = conf->remote_ifindex;
2ddc: 8b 90 48 02 00 00 mov 0x248(%rax),%edx
if (!lowerdev) {
2de2: bf 01 00 00 00 mov $0x1,%edi
})
static __always_inline
void __read_once_size(const volatile void *p, void *res, int size)
{
__READ_ONCE_SIZE;
2de7: be 46 00 00 00 mov $0x46,%esi
}
#if IS_ENABLED(CONFIG_IPV6)
if (use_ipv6) {
struct inet6_dev *idev = __in6_dev_get(lowerdev);
if (idev && idev->cnf.disable_ipv6) {
2dec: e9 54 ff ff ff jmpq 2d45 <vxlan_dev_configure+0x445>
2df1: 44 0f b7 80 4e 02 00 movzwl 0x24e(%rax),%r8d
2df8: 00
2df9: 89 d6 mov %edx,%esi
2dfb: e9 64 ff ff ff jmpq 2d64 <vxlan_dev_configure+0x464>
return -EPERM;
}
}
#endif
if (!conf->mtu)
2e00: 4c 89 ef mov %r13,%rdi
2e03: 89 45 d4 mov %eax,-0x2c(%rbp)
2e06: e8 c5 f1 ff ff callq 1fd0 <vxlan_fdb_delete_default>
2e0b: 8b 45 d4 mov -0x2c(%rbp),%eax
dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
2e0e: 48 83 c4 20 add $0x20,%rsp
2e12: 5b pop %rbx
2e13: 41 5c pop %r12
2e15: 41 5d pop %r13
2e17: 41 5e pop %r14
2e19: 41 5f pop %r15
2e1b: 5d pop %rbp
2e1c: c3 retq
2e1d: b8 ff ff 00 00 mov $0xffff,%eax
needed_headroom = lowerdev->hard_header_len;
2e22: e9 43 ff ff ff jmpq 2d6a <vxlan_dev_configure+0x46a>
2e27: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
2e2e: e8 00 00 00 00 callq 2e33 <vxlan_dev_configure+0x533>
return err;
}
err = register_netdevice(dev);
if (err) {
vxlan_fdb_delete_default(vxlan);
2e33: b8 ed ff ff ff mov $0xffffffed,%eax
2e38: e9 53 fe ff ff jmpq 2c90 <vxlan_dev_configure+0x390>
return err;
2e3d: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
}
list_add(&vxlan->next, &vn->vxlan_list);
return 0;
}
2e44: e8 00 00 00 00 callq 2e49 <vxlan_dev_configure+0x549>
2e49: b8 ea ff ff ff mov $0xffffffea,%eax
static int __vxlan_change_mtu(struct net_device *dev,
struct net_device *lowerdev,
struct vxlan_rdst *dst, int new_mtu, bool strict)
{
int max_mtu = IP_MAX_MTU;
2e4e: e9 3d fe ff ff jmpq 2c90 <vxlan_dev_configure+0x390>
2e53: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
if (conf->remote_ifindex) {
lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
dst->remote_ifindex = conf->remote_ifindex;
if (!lowerdev) {
pr_info("ifindex %d does not exist\n", dst->remote_ifindex);
2e5a: e8 00 00 00 00 callq 2e5f <vxlan_dev_configure+0x55f>
2e5f: b8 ea ff ff ff mov $0xffffffea,%eax
return -ENODEV;
2e64: e9 27 fe ff ff jmpq 2c90 <vxlan_dev_configure+0x390>
2e69: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
use_ipv6 = true;
vxlan->flags |= VXLAN_F_IPV6;
}
if (conf->label && !use_ipv6) {
pr_info("label only supported in use with IPv6\n");
2e70: e8 00 00 00 00 callq 2e75 <vxlan_dev_configure+0x575>
2e75: b8 ea ff ff ff mov $0xffffffea,%eax
return -EINVAL;
2e7a: e9 11 fe ff ff jmpq 2c90 <vxlan_dev_configure+0x390>
2e7f: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
if (!conf->mtu)
dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
needed_headroom = lowerdev->hard_header_len;
} else if (vxlan_addr_multicast(&dst->remote_ip)) {
pr_info("multicast destination requires interface to be specified\n");
2e86: e8 00 00 00 00 callq 2e8b <vxlan_dev_configure+0x58b>
2e8b: b8 ff ff ff ff mov $0xffffffff,%eax
return -EINVAL;
2e90: e9 fb fd ff ff jmpq 2c90 <vxlan_dev_configure+0x390>
2e95: 90 nop
2e96: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
2e9d: 00 00 00
0000000000002ea0 <vxlan_newlink>:
* This can be relaxed later; in such case, the other side
* of the PtP link will have to be provided.
*/
if ((conf->flags & ~VXLAN_F_ALLOWED_GPE) ||
!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
pr_info("unsupported combination of extensions\n");
2ea0: e8 00 00 00 00 callq 2ea5 <vxlan_newlink+0x5>
return -EINVAL;
2ea5: 55 push %rbp
2ea6: 48 89 e5 mov %rsp,%rbp
2ea9: 41 57 push %r15
2eab: 41 56 push %r14
2ead: 41 55 push %r13
#if IS_ENABLED(CONFIG_IPV6)
if (use_ipv6) {
struct inet6_dev *idev = __in6_dev_get(lowerdev);
if (idev && idev->cnf.disable_ipv6) {
pr_info("IPv6 is disabled via sysctl\n");
2eaf: 41 54 push %r12
2eb1: 49 89 fd mov %rdi,%r13
2eb4: 53 push %rbx
2eb5: 48 89 cb mov %rcx,%rbx
2eb8: b9 0d 00 00 00 mov $0xd,%ecx
return -EPERM;
2ebd: 49 89 f6 mov %rsi,%r14
2ec0: 49 89 d7 mov %rdx,%r15
2ec3: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
2ec7: 48 83 c4 80 add $0xffffffffffffff80,%rsp
2ecb: 4c 8d 64 24 10 lea 0x10(%rsp),%r12
return 0;
}
static int vxlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
2ed0: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
2ed7: 00 00
2ed9: 48 89 44 24 78 mov %rax,0x78(%rsp)
2ede: 31 c0 xor %eax,%eax
2ee0: 4c 89 e7 mov %r12,%rdi
2ee3: f3 48 ab rep stos %rax,%es:(%rdi)
2ee6: 48 8b 43 08 mov 0x8(%rbx),%rax
struct vxlan_config conf;
memset(&conf, 0, sizeof(conf));
2eea: 48 85 c0 test %rax,%rax
return 0;
}
static int vxlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
2eed: 74 09 je 2ef8 <vxlan_newlink+0x58>
2eef: 8b 40 04 mov 0x4(%rax),%eax
2ef2: 0f c8 bswap %eax
2ef4: 89 44 24 48 mov %eax,0x48(%rsp)
2ef8: 48 8b 43 10 mov 0x10(%rbx),%rax
struct vxlan_config conf;
memset(&conf, 0, sizeof(conf));
2efc: 48 85 c0 test %rax,%rax
2eff: 0f 84 df 02 00 00 je 31e4 <vxlan_newlink+0x344>
return 0;
}
static int vxlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
2f05: 8b 40 04 mov 0x4(%rax),%eax
2f08: 89 44 24 14 mov %eax,0x14(%rsp)
2f0c: 48 8b 43 20 mov 0x20(%rbx),%rax
struct vxlan_config conf;
memset(&conf, 0, sizeof(conf));
2f10: 48 85 c0 test %rax,%rax
2f13: 0f 84 8c 02 00 00 je 31a5 <vxlan_newlink+0x305>
if (data[IFLA_VXLAN_ID])
2f19: 8b 40 04 mov 0x4(%rax),%eax
2f1c: ba 02 00 00 00 mov $0x2,%edx
conf.vni = cpu_to_be32(nla_get_u32(data[IFLA_VXLAN_ID]));
2f21: 66 89 54 24 2c mov %dx,0x2c(%rsp)
2f26: 89 44 24 30 mov %eax,0x30(%rsp)
if (data[IFLA_VXLAN_GROUP]) {
2f2a: 48 8b 43 18 mov 0x18(%rbx),%rax
2f2e: 48 85 c0 test %rax,%rax
2f31: 74 07 je 2f3a <vxlan_newlink+0x9a>
2f33: 8b 40 04 mov 0x4(%rax),%eax
* nla_get_in_addr - return payload of IPv4 address attribute
* @nla: IPv4 address netlink attribute
*/
static inline __be32 nla_get_in_addr(const struct nlattr *nla)
{
return *(__be32 *) nla_data(nla);
2f36: 89 44 24 4c mov %eax,0x4c(%rsp)
conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
2f3a: 48 8b 43 30 mov 0x30(%rbx),%rax
conf.remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
conf.remote_ip.sa.sa_family = AF_INET6;
}
if (data[IFLA_VXLAN_LOCAL]) {
2f3e: 48 85 c0 test %rax,%rax
2f41: 74 08 je 2f4b <vxlan_newlink+0xab>
2f43: 0f b6 40 04 movzbl 0x4(%rax),%eax
2f47: 88 44 24 5a mov %al,0x5a(%rsp)
2f4b: 48 8b 43 28 mov 0x28(%rbx),%rax
conf.saddr.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_LOCAL]);
conf.saddr.sa.sa_family = AF_INET;
2f4f: 48 85 c0 test %rax,%rax
2f52: 74 08 je 2f5c <vxlan_newlink+0xbc>
2f54: 0f b6 40 04 movzbl 0x4(%rax),%eax
conf.remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
conf.remote_ip.sa.sa_family = AF_INET6;
}
if (data[IFLA_VXLAN_LOCAL]) {
conf.saddr.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_LOCAL]);
2f58: 88 44 24 5b mov %al,0x5b(%rsp)
/* TODO: respect scope id */
conf.saddr.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_LOCAL6]);
conf.saddr.sa.sa_family = AF_INET6;
}
if (data[IFLA_VXLAN_LINK])
2f5c: 48 8b 83 d0 00 00 00 mov 0xd0(%rbx),%rax
conf.remote_ifindex = nla_get_u32(data[IFLA_VXLAN_LINK]);
2f63: 48 85 c0 test %rax,%rax
2f66: 74 0c je 2f74 <vxlan_newlink+0xd4>
2f68: 8b 40 04 mov 0x4(%rax),%eax
if (data[IFLA_VXLAN_TOS])
2f6b: 25 00 0f ff ff and $0xffff0f00,%eax
2f70: 89 44 24 5c mov %eax,0x5c(%rsp)
* nla_get_u8 - return payload of u8 attribute
* @nla: u8 netlink attribute
*/
static inline u8 nla_get_u8(const struct nlattr *nla)
{
return *(u8 *) nla_data(nla);
2f74: 48 8b 43 38 mov 0x38(%rbx),%rax
conf.tos = nla_get_u8(data[IFLA_VXLAN_TOS]);
2f78: 48 85 c0 test %rax,%rax
if (data[IFLA_VXLAN_TTL])
2f7b: 0f 84 a7 01 00 00 je 3128 <vxlan_newlink+0x288>
2f81: 80 78 04 00 cmpb $0x0,0x4(%rax)
2f85: 0f 85 9d 01 00 00 jne 3128 <vxlan_newlink+0x288>
conf.ttl = nla_get_u8(data[IFLA_VXLAN_TTL]);
2f8b: 48 8b 43 40 mov 0x40(%rbx),%rax
if (data[IFLA_VXLAN_LABEL])
2f8f: 48 85 c0 test %rax,%rax
2f92: 74 08 je 2f9c <vxlan_newlink+0xfc>
2f94: 8b 40 04 mov 0x4(%rax),%eax
2f97: 48 89 44 24 68 mov %rax,0x68(%rsp)
conf.label = nla_get_be32(data[IFLA_VXLAN_LABEL]) &
2f9c: 48 8b 43 58 mov 0x58(%rbx),%rax
2fa0: 48 85 c0 test %rax,%rax
2fa3: 74 0a je 2faf <vxlan_newlink+0x10f>
IPV6_FLOWLABEL_MASK;
if (!data[IFLA_VXLAN_LEARNING] || nla_get_u8(data[IFLA_VXLAN_LEARNING]))
2fa5: 80 78 04 00 cmpb $0x0,0x4(%rax)
2fa9: 0f 85 ec 01 00 00 jne 319b <vxlan_newlink+0x2fb>
2faf: 48 8b 43 60 mov 0x60(%rbx),%rax
2fb3: 48 85 c0 test %rax,%rax
2fb6: 74 0a je 2fc2 <vxlan_newlink+0x122>
2fb8: 80 78 04 00 cmpb $0x0,0x4(%rax)
conf.flags |= VXLAN_F_LEARN;
if (data[IFLA_VXLAN_AGEING])
2fbc: 0f 85 cf 01 00 00 jne 3191 <vxlan_newlink+0x2f1>
2fc2: 48 8b 43 68 mov 0x68(%rbx),%rax
conf.age_interval = nla_get_u32(data[IFLA_VXLAN_AGEING]);
2fc6: 48 85 c0 test %rax,%rax
2fc9: 74 0a je 2fd5 <vxlan_newlink+0x135>
2fcb: 80 78 04 00 cmpb $0x0,0x4(%rax)
if (data[IFLA_VXLAN_PROXY] && nla_get_u8(data[IFLA_VXLAN_PROXY]))
2fcf: 0f 85 b2 01 00 00 jne 3187 <vxlan_newlink+0x2e7>
2fd5: 48 8b 43 70 mov 0x70(%rbx),%rax
2fd9: 48 85 c0 test %rax,%rax
2fdc: 74 0a je 2fe8 <vxlan_newlink+0x148>
2fde: 80 78 04 00 cmpb $0x0,0x4(%rax)
conf.flags |= VXLAN_F_PROXY;
if (data[IFLA_VXLAN_RSC] && nla_get_u8(data[IFLA_VXLAN_RSC]))
2fe2: 0f 85 95 01 00 00 jne 317d <vxlan_newlink+0x2dd>
2fe8: 48 8b 43 48 mov 0x48(%rbx),%rax
2fec: 48 85 c0 test %rax,%rax
2fef: 74 07 je 2ff8 <vxlan_newlink+0x158>
2ff1: 8b 40 04 mov 0x4(%rax),%eax
conf.flags |= VXLAN_F_RSC;
if (data[IFLA_VXLAN_L2MISS] && nla_get_u8(data[IFLA_VXLAN_L2MISS]))
2ff4: 89 44 24 70 mov %eax,0x70(%rsp)
2ff8: 48 8b 83 c8 00 00 00 mov 0xc8(%rbx),%rax
2fff: 48 85 c0 test %rax,%rax
3002: 74 0a je 300e <vxlan_newlink+0x16e>
3004: 80 78 04 00 cmpb $0x0,0x4(%rax)
conf.flags |= VXLAN_F_L2MISS;
if (data[IFLA_VXLAN_L3MISS] && nla_get_u8(data[IFLA_VXLAN_L3MISS]))
3008: 0f 85 62 01 00 00 jne 3170 <vxlan_newlink+0x2d0>
300e: 48 8b 43 50 mov 0x50(%rbx),%rax
3012: 48 85 c0 test %rax,%rax
3015: 74 1a je 3031 <vxlan_newlink+0x191>
3017: 0f b7 50 04 movzwl 0x4(%rax),%edx
conf.flags |= VXLAN_F_L3MISS;
if (data[IFLA_VXLAN_LIMIT])
301b: 66 c1 c2 08 rol $0x8,%dx
301f: 66 89 54 24 56 mov %dx,0x56(%rsp)
conf.addrmax = nla_get_u32(data[IFLA_VXLAN_LIMIT]);
3024: 0f b7 40 06 movzwl 0x6(%rax),%eax
if (data[IFLA_VXLAN_COLLECT_METADATA] &&
3028: 66 c1 c0 08 rol $0x8,%ax
302c: 66 89 44 24 58 mov %ax,0x58(%rsp)
3031: 48 8b 43 78 mov 0x78(%rbx),%rax
3035: 48 85 c0 test %rax,%rax
3038: 74 09 je 3043 <vxlan_newlink+0x1a3>
303a: 0f b7 40 04 movzwl 0x4(%rax),%eax
nla_get_u8(data[IFLA_VXLAN_COLLECT_METADATA]))
conf.flags |= VXLAN_F_COLLECT_METADATA;
if (data[IFLA_VXLAN_PORT_RANGE]) {
303e: 66 89 44 24 54 mov %ax,0x54(%rsp)
3043: 48 8b 83 90 00 00 00 mov 0x90(%rbx),%rax
const struct ifla_vxlan_port_range *p
= nla_data(data[IFLA_VXLAN_PORT_RANGE]);
conf.port_min = ntohs(p->low);
304a: 48 85 c0 test %rax,%rax
304d: 74 0a je 3059 <vxlan_newlink+0x1b9>
304f: 80 78 04 00 cmpb $0x0,0x4(%rax)
3053: 0f 84 0d 01 00 00 je 3166 <vxlan_newlink+0x2c6>
conf.port_max = ntohs(p->high);
3059: 48 8b 83 98 00 00 00 mov 0x98(%rbx),%rax
3060: 48 85 c0 test %rax,%rax
}
if (data[IFLA_VXLAN_PORT])
3063: 74 0a je 306f <vxlan_newlink+0x1cf>
3065: 80 78 04 00 cmpb $0x0,0x4(%rax)
3069: 0f 85 ea 00 00 00 jne 3159 <vxlan_newlink+0x2b9>
conf.dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
306f: 48 8b 83 a0 00 00 00 mov 0xa0(%rbx),%rax
if (data[IFLA_VXLAN_UDP_CSUM] &&
3076: 48 85 c0 test %rax,%rax
3079: 74 0a je 3085 <vxlan_newlink+0x1e5>
307b: 80 78 04 00 cmpb $0x0,0x4(%rax)
307f: 0f 85 c7 00 00 00 jne 314c <vxlan_newlink+0x2ac>
3085: 48 8b 83 a8 00 00 00 mov 0xa8(%rbx),%rax
!nla_get_u8(data[IFLA_VXLAN_UDP_CSUM]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM_TX;
if (data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX] &&
308c: 48 85 c0 test %rax,%rax
308f: 74 0a je 309b <vxlan_newlink+0x1fb>
3091: 80 78 04 00 cmpb $0x0,0x4(%rax)
3095: 0f 85 a4 00 00 00 jne 313f <vxlan_newlink+0x29f>
309b: 48 8b 83 b0 00 00 00 mov 0xb0(%rbx),%rax
nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM6_TX;
if (data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX] &&
30a2: 48 85 c0 test %rax,%rax
30a5: 74 0a je 30b1 <vxlan_newlink+0x211>
30a7: 80 78 04 00 cmpb $0x0,0x4(%rax)
30ab: 0f 85 81 00 00 00 jne 3132 <vxlan_newlink+0x292>
30b1: 48 83 bb b8 00 00 00 cmpq $0x0,0xb8(%rbx)
30b8: 00
nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM6_RX;
if (data[IFLA_VXLAN_REMCSUM_TX] &&
30b9: 74 08 je 30c3 <vxlan_newlink+0x223>
30bb: 81 4c 24 60 00 08 00 orl $0x800,0x60(%rsp)
30c2: 00
30c3: 48 83 bb d8 00 00 00 cmpq $0x0,0xd8(%rbx)
30ca: 00
nla_get_u8(data[IFLA_VXLAN_REMCSUM_TX]))
conf.flags |= VXLAN_F_REMCSUM_TX;
if (data[IFLA_VXLAN_REMCSUM_RX] &&
30cb: 74 08 je 30d5 <vxlan_newlink+0x235>
30cd: 81 4c 24 60 00 40 00 orl $0x4000,0x60(%rsp)
30d4: 00
30d5: 48 83 bb c0 00 00 00 cmpq $0x0,0xc0(%rbx)
30dc: 00
30dd: 74 08 je 30e7 <vxlan_newlink+0x247>
30df: 81 4c 24 60 00 10 00 orl $0x1000,0x60(%rsp)
30e6: 00
nla_get_u8(data[IFLA_VXLAN_REMCSUM_RX]))
conf.flags |= VXLAN_F_REMCSUM_RX;
if (data[IFLA_VXLAN_GBP])
30e7: 49 8b 47 20 mov 0x20(%r15),%rax
conf.flags |= VXLAN_F_GBP;
30eb: 48 85 c0 test %rax,%rax
30ee: 74 07 je 30f7 <vxlan_newlink+0x257>
30f0: 8b 40 04 mov 0x4(%rax),%eax
if (data[IFLA_VXLAN_GPE])
30f3: 89 44 24 50 mov %eax,0x50(%rsp)
30f7: 4c 89 e2 mov %r12,%rdx
30fa: 4c 89 f6 mov %r14,%rsi
conf.flags |= VXLAN_F_GPE;
30fd: 4c 89 ef mov %r13,%rdi
3100: e8 fb f7 ff ff callq 2900 <vxlan_dev_configure>
if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL])
3105: 48 8b 4c 24 78 mov 0x78(%rsp),%rcx
310a: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
3111: 00 00
conf.flags |= VXLAN_F_REMCSUM_NOPARTIAL;
3113: 0f 85 0a 01 00 00 jne 3223 <vxlan_newlink+0x383>
if (tb[IFLA_MTU])
3119: 48 8d 65 d8 lea -0x28(%rbp),%rsp
311d: 5b pop %rbx
311e: 41 5c pop %r12
conf.mtu = nla_get_u32(tb[IFLA_MTU]);
3120: 41 5d pop %r13
3122: 41 5e pop %r14
3124: 41 5f pop %r15
3126: 5d pop %rbp
return vxlan_dev_configure(src_net, dev, &conf);
3127: c3 retq
3128: 83 4c 24 60 01 orl $0x1,0x60(%rsp)
312d: e9 59 fe ff ff jmpq 2f8b <vxlan_newlink+0xeb>
3132: 81 4c 24 60 00 04 00 orl $0x400,0x60(%rsp)
3139: 00
}
313a: e9 72 ff ff ff jmpq 30b1 <vxlan_newlink+0x211>
313f: 81 4c 24 60 00 02 00 orl $0x200,0x60(%rsp)
3146: 00
3147: e9 4f ff ff ff jmpq 309b <vxlan_newlink+0x1fb>
314c: 81 4c 24 60 00 01 00 orl $0x100,0x60(%rsp)
3153: 00
3154: e9 2c ff ff ff jmpq 3085 <vxlan_newlink+0x1e5>
if (data[IFLA_VXLAN_LABEL])
conf.label = nla_get_be32(data[IFLA_VXLAN_LABEL]) &
IPV6_FLOWLABEL_MASK;
if (!data[IFLA_VXLAN_LEARNING] || nla_get_u8(data[IFLA_VXLAN_LEARNING]))
conf.flags |= VXLAN_F_LEARN;
3159: 81 4c 24 60 80 00 00 orl $0x80,0x60(%rsp)
3160: 00
3161: e9 09 ff ff ff jmpq 306f <vxlan_newlink+0x1cf>
nla_get_u8(data[IFLA_VXLAN_REMCSUM_TX]))
conf.flags |= VXLAN_F_REMCSUM_TX;
if (data[IFLA_VXLAN_REMCSUM_RX] &&
nla_get_u8(data[IFLA_VXLAN_REMCSUM_RX]))
conf.flags |= VXLAN_F_REMCSUM_RX;
3166: 83 4c 24 60 40 orl $0x40,0x60(%rsp)
316b: e9 e9 fe ff ff jmpq 3059 <vxlan_newlink+0x1b9>
nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM6_RX;
if (data[IFLA_VXLAN_REMCSUM_TX] &&
nla_get_u8(data[IFLA_VXLAN_REMCSUM_TX]))
conf.flags |= VXLAN_F_REMCSUM_TX;
3170: 81 4c 24 60 00 20 00 orl $0x2000,0x60(%rsp)
3177: 00
3178: e9 91 fe ff ff jmpq 300e <vxlan_newlink+0x16e>
nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM6_TX;
if (data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX] &&
nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM6_RX;
317d: 83 4c 24 60 10 orl $0x10,0x60(%rsp)
3182: e9 61 fe ff ff jmpq 2fe8 <vxlan_newlink+0x148>
3187: 83 4c 24 60 08 orl $0x8,0x60(%rsp)
!nla_get_u8(data[IFLA_VXLAN_UDP_CSUM]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM_TX;
if (data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX] &&
nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM6_TX;
318c: e9 44 fe ff ff jmpq 2fd5 <vxlan_newlink+0x135>
3191: 83 4c 24 60 04 orl $0x4,0x60(%rsp)
if (data[IFLA_VXLAN_PORT])
conf.dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
if (data[IFLA_VXLAN_UDP_CSUM] &&
!nla_get_u8(data[IFLA_VXLAN_UDP_CSUM]))
conf.flags |= VXLAN_F_UDP_ZERO_CSUM_TX;
3196: e9 27 fe ff ff jmpq 2fc2 <vxlan_newlink+0x122>
319b: 83 4c 24 60 02 orl $0x2,0x60(%rsp)
if (data[IFLA_VXLAN_LIMIT])
conf.addrmax = nla_get_u32(data[IFLA_VXLAN_LIMIT]);
if (data[IFLA_VXLAN_COLLECT_METADATA] &&
nla_get_u8(data[IFLA_VXLAN_COLLECT_METADATA]))
conf.flags |= VXLAN_F_COLLECT_METADATA;
31a0: e9 0a fe ff ff jmpq 2faf <vxlan_newlink+0x10f>
31a5: 48 8b b3 88 00 00 00 mov 0x88(%rbx),%rsi
31ac: 48 85 f6 test %rsi,%rsi
if (data[IFLA_VXLAN_L2MISS] && nla_get_u8(data[IFLA_VXLAN_L2MISS]))
conf.flags |= VXLAN_F_L2MISS;
if (data[IFLA_VXLAN_L3MISS] && nla_get_u8(data[IFLA_VXLAN_L3MISS]))
conf.flags |= VXLAN_F_L3MISS;
31af: 0f 84 75 fd ff ff je 2f2a <vxlan_newlink+0x8a>
31b5: ba 10 00 00 00 mov $0x10,%edx
if (data[IFLA_VXLAN_RSC] && nla_get_u8(data[IFLA_VXLAN_RSC]))
conf.flags |= VXLAN_F_RSC;
if (data[IFLA_VXLAN_L2MISS] && nla_get_u8(data[IFLA_VXLAN_L2MISS]))
conf.flags |= VXLAN_F_L2MISS;
31ba: 48 89 e7 mov %rsp,%rdi
31bd: e8 00 00 00 00 callq 31c2 <vxlan_newlink+0x322>
if (data[IFLA_VXLAN_PROXY] && nla_get_u8(data[IFLA_VXLAN_PROXY]))
conf.flags |= VXLAN_F_PROXY;
if (data[IFLA_VXLAN_RSC] && nla_get_u8(data[IFLA_VXLAN_RSC]))
conf.flags |= VXLAN_F_RSC;
31c2: 48 8b 04 24 mov (%rsp),%rax
31c6: 48 8b 54 24 08 mov 0x8(%rsp),%rdx
if (data[IFLA_VXLAN_AGEING])
conf.age_interval = nla_get_u32(data[IFLA_VXLAN_AGEING]);
if (data[IFLA_VXLAN_PROXY] && nla_get_u8(data[IFLA_VXLAN_PROXY]))
conf.flags |= VXLAN_F_PROXY;
31cb: 48 89 44 24 34 mov %rax,0x34(%rsp)
31d0: b8 0a 00 00 00 mov $0xa,%eax
}
if (data[IFLA_VXLAN_LOCAL]) {
conf.saddr.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_LOCAL]);
conf.saddr.sa.sa_family = AF_INET;
} else if (data[IFLA_VXLAN_LOCAL6]) {
31d5: 48 89 54 24 3c mov %rdx,0x3c(%rsp)
31da: 66 89 44 24 2c mov %ax,0x2c(%rsp)
31df: e9 46 fd ff ff jmpq 2f2a <vxlan_newlink+0x8a>
31e4: 48 8b b3 80 00 00 00 mov 0x80(%rbx),%rsi
*/
static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
{
struct in6_addr tmp;
nla_memcpy(&tmp, nla, sizeof(tmp));
31eb: 48 85 f6 test %rsi,%rsi
31ee: 0f 84 18 fd ff ff je 2f0c <vxlan_newlink+0x6c>
return tmp;
31f4: ba 10 00 00 00 mov $0x10,%edx
31f9: 48 89 e7 mov %rsp,%rdi
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
/* TODO: respect scope id */
conf.saddr.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_LOCAL6]);
31fc: e8 00 00 00 00 callq 3201 <vxlan_newlink+0x361>
conf.saddr.sa.sa_family = AF_INET6;
3201: 48 8b 04 24 mov (%rsp),%rax
} else if (data[IFLA_VXLAN_LOCAL6]) {
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
/* TODO: respect scope id */
conf.saddr.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_LOCAL6]);
3205: 48 8b 54 24 08 mov 0x8(%rsp),%rdx
conf.saddr.sa.sa_family = AF_INET6;
320a: b9 0a 00 00 00 mov $0xa,%ecx
320f: 66 89 4c 24 10 mov %cx,0x10(%rsp)
if (data[IFLA_VXLAN_ID])
conf.vni = cpu_to_be32(nla_get_u32(data[IFLA_VXLAN_ID]));
if (data[IFLA_VXLAN_GROUP]) {
conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
} else if (data[IFLA_VXLAN_GROUP6]) {
3214: 48 89 44 24 18 mov %rax,0x18(%rsp)
3219: 48 89 54 24 20 mov %rdx,0x20(%rsp)
321e: e9 e9 fc ff ff jmpq 2f0c <vxlan_newlink+0x6c>
3223: e8 00 00 00 00 callq 3228 <vxlan_newlink+0x388>
*/
static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
{
struct in6_addr tmp;
nla_memcpy(&tmp, nla, sizeof(tmp));
3228: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
322f: 00
0000000000003230 <vxlan_dev_create>:
3230: e8 00 00 00 00 callq 3235 <vxlan_dev_create+0x5>
return tmp;
3235: 55 push %rbp
3236: 0f b6 d2 movzbl %dl,%edx
3239: 48 89 e5 mov %rsp,%rbp
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
conf.remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
conf.remote_ip.sa.sa_family = AF_INET6;
323c: 41 55 push %r13
323e: 41 54 push %r12
3240: 53 push %rbx
3241: 4c 8d 85 80 fe ff ff lea -0x180(%rbp),%r8
conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
} else if (data[IFLA_VXLAN_GROUP6]) {
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
conf.remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
3248: 49 89 fd mov %rdi,%r13
324b: 49 89 cc mov %rcx,%r12
324e: b9 2c 00 00 00 mov $0x2c,%ecx
if (tb[IFLA_MTU])
conf.mtu = nla_get_u32(tb[IFLA_MTU]);
return vxlan_dev_configure(src_net, dev, &conf);
}
3253: 48 81 ec 80 01 00 00 sub $0x180,%rsp
325a: 4c 89 c7 mov %r8,%rdi
325d: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
3264: 00 00
struct net_device *dev;
int err;
memset(&tb, 0, sizeof(tb));
dev = rtnl_create_link(net, name, name_assign_type,
3266: 48 89 45 e0 mov %rax,-0x20(%rbp)
};
struct net_device *vxlan_dev_create(struct net *net, const char *name,
u8 name_assign_type,
struct vxlan_config *conf)
{
326a: 31 c0 xor %eax,%eax
326c: f3 48 ab rep stos %rax,%es:(%rdi)
326f: 48 c7 c1 00 00 00 00 mov $0x0,%rcx
struct nlattr *tb[IFLA_MAX + 1];
struct net_device *dev;
int err;
memset(&tb, 0, sizeof(tb));
3276: 4c 89 ef mov %r13,%rdi
};
struct net_device *vxlan_dev_create(struct net *net, const char *name,
u8 name_assign_type,
struct vxlan_config *conf)
{
3279: e8 00 00 00 00 callq 327e <vxlan_dev_create+0x4e>
struct nlattr *tb[IFLA_MAX + 1];
struct net_device *dev;
int err;
memset(&tb, 0, sizeof(tb));
327e: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
};
struct net_device *vxlan_dev_create(struct net *net, const char *name,
u8 name_assign_type,
struct vxlan_config *conf)
{
3284: 48 89 c3 mov %rax,%rbx
3287: 0f 87 8e 00 00 00 ja 331b <vxlan_dev_create+0xeb>
328d: 4c 89 e2 mov %r12,%rdx
3290: 48 89 c6 mov %rax,%rsi
3293: 4c 89 ef mov %r13,%rdi
3296: e8 65 f6 ff ff callq 2900 <vxlan_dev_configure>
329b: 85 c0 test %eax,%eax
struct nlattr *tb[IFLA_MAX + 1];
struct net_device *dev;
int err;
memset(&tb, 0, sizeof(tb));
329d: 78 31 js 32d0 <vxlan_dev_create+0xa0>
dev = rtnl_create_link(net, name, name_assign_type,
329f: 31 f6 xor %esi,%esi
32a1: 48 89 df mov %rbx,%rdi
32a4: e8 00 00 00 00 callq 32a9 <vxlan_dev_create+0x79>
32a9: 85 c0 test %eax,%eax
32ab: 48 89 df mov %rbx,%rdi
&vxlan_link_ops, tb);
if (IS_ERR(dev))
32ae: 78 37 js 32e7 <vxlan_dev_create+0xb7>
32b0: 48 8b 4d e0 mov -0x20(%rbp),%rcx
struct net_device *dev;
int err;
memset(&tb, 0, sizeof(tb));
dev = rtnl_create_link(net, name, name_assign_type,
32b4: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
32bb: 00 00
&vxlan_link_ops, tb);
if (IS_ERR(dev))
return dev;
err = vxlan_dev_configure(net, dev, conf);
32bd: 48 89 f8 mov %rdi,%rax
32c0: 75 5e jne 3320 <vxlan_dev_create+0xf0>
32c2: 48 81 c4 80 01 00 00 add $0x180,%rsp
32c9: 5b pop %rbx
32ca: 41 5c pop %r12
if (err < 0) {
32cc: 41 5d pop %r13
32ce: 5d pop %rbp
free_netdev(dev);
return ERR_PTR(err);
}
err = rtnl_configure_link(dev, NULL);
32cf: c3 retq
32d0: 48 89 df mov %rbx,%rdi
32d3: 89 85 6c fe ff ff mov %eax,-0x194(%rbp)
if (err < 0) {
32d9: e8 00 00 00 00 callq 32de <vxlan_dev_create+0xae>
32de: 48 63 bd 6c fe ff ff movslq -0x194(%rbp),%rdi
unregister_netdevice_many(&list_kill);
return ERR_PTR(err);
}
return dev;
}
32e5: eb c9 jmp 32b0 <vxlan_dev_create+0x80>
32e7: 4c 8d a5 70 fe ff ff lea -0x190(%rbp),%r12
32ee: 89 85 6c fe ff ff mov %eax,-0x194(%rbp)
32f4: 4c 89 e6 mov %r12,%rsi
32f7: 4c 89 a5 70 fe ff ff mov %r12,-0x190(%rbp)
32fe: 4c 89 a5 78 fe ff ff mov %r12,-0x188(%rbp)
if (IS_ERR(dev))
return dev;
err = vxlan_dev_configure(net, dev, conf);
if (err < 0) {
free_netdev(dev);
3305: e8 f6 d5 ff ff callq 900 <vxlan_dellink>
330a: 4c 89 e7 mov %r12,%rdi
330d: e8 00 00 00 00 callq 3312 <vxlan_dev_create+0xe2>
3312: 48 63 bd 6c fe ff ff movslq -0x194(%rbp),%rdi
return ERR_PTR(err);
}
err = rtnl_configure_link(dev, NULL);
if (err < 0) {
LIST_HEAD(list_kill);
3319: eb 95 jmp 32b0 <vxlan_dev_create+0x80>
331b: 48 89 c7 mov %rax,%rdi
331e: eb 90 jmp 32b0 <vxlan_dev_create+0x80>
3320: e8 00 00 00 00 callq 3325 <vxlan_dev_create+0xf5>
vxlan_dellink(dev, &list_kill);
3325: 90 nop
3326: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
332d: 00 00 00
0000000000003330 <vxlan_snoop>:
return ERR_PTR(err);
}
err = rtnl_configure_link(dev, NULL);
if (err < 0) {
LIST_HEAD(list_kill);
3330: e8 00 00 00 00 callq 3335 <vxlan_snoop+0x5>
vxlan_dellink(dev, &list_kill);
3335: 55 push %rbp
3336: 48 89 e5 mov %rsp,%rbp
3339: 41 57 push %r15
unregister_netdevice_many(&list_kill);
333b: 41 56 push %r14
333d: 4c 8d b7 40 08 00 00 lea 0x840(%rdi),%r14
3344: 41 55 push %r13
3346: 41 54 push %r12
3348: 53 push %rbx
3349: 49 89 fd mov %rdi,%r13
memset(&tb, 0, sizeof(tb));
dev = rtnl_create_link(net, name, name_assign_type,
&vxlan_link_ops, tb);
if (IS_ERR(dev))
return dev;
334c: 49 89 f4 mov %rsi,%r12
334f: 4c 89 f7 mov %r14,%rdi
unregister_netdevice_many(&list_kill);
return ERR_PTR(err);
}
return dev;
}
3352: 48 89 d6 mov %rdx,%rsi
3355: 49 89 d7 mov %rdx,%r15
3358: 48 83 ec 28 sub $0x28,%rsp
335c: e8 9f cc ff ff callq 0 <__vxlan_find_mac>
* and Tunnel endpoint.
* Return true if packet is bogus and should be dropped.
*/
static bool vxlan_snoop(struct net_device *dev,
union vxlan_addr *src_ip, const u8 *src_mac)
{
3361: 48 85 c0 test %rax,%rax
3364: 74 7d je 33e3 <vxlan_snoop+0xb3>
3366: 48 89 c3 mov %rax,%rbx
3369: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 3370 <vxlan_snoop+0x40>
3370: 4c 8b 4b 30 mov 0x30(%rbx),%r9
3374: 48 89 43 28 mov %rax,0x28(%rbx)
3378: 41 0f b7 41 d8 movzwl -0x28(%r9),%eax
337d: 66 41 3b 04 24 cmp (%r12),%ax
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
3382: 74 1e je 33a2 <vxlan_snoop+0x72>
3384: f6 43 46 40 testb $0x40,0x46(%rbx)
* and Tunnel endpoint.
* Return true if packet is bogus and should be dropped.
*/
static bool vxlan_snoop(struct net_device *dev,
union vxlan_addr *src_ip, const u8 *src_mac)
{
3388: b8 01 00 00 00 mov $0x1,%eax
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
338d: 0f 84 86 00 00 00 je 3419 <vxlan_snoop+0xe9>
if (f)
3393: 48 83 c4 28 add $0x28,%rsp
3397: 5b pop %rbx
3398: 41 5c pop %r12
f->used = jiffies;
339a: 41 5d pop %r13
339c: 41 5e pop %r14
339e: 41 5f pop %r15
33a0: 5d pop %rbp
33a1: c3 retq
33a2: 66 83 f8 0a cmp $0xa,%ax
33a6: 74 21 je 33c9 <vxlan_snoop+0x99>
#if IS_ENABLED(CONFIG_IPV6)
static inline
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
{
if (a->sa.sa_family != b->sa.sa_family)
33a8: 41 8b 44 24 04 mov 0x4(%r12),%eax
33ad: 41 39 41 dc cmp %eax,-0x24(%r9)
33b1: 0f 94 c0 sete %al
if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip)))
return false;
/* Don't migrate static entries, drop packets */
if (f->state & NUD_NOARP)
33b4: 84 c0 test %al,%al
33b6: 74 cc je 3384 <vxlan_snoop+0x54>
return true;
33b8: 48 83 c4 28 add $0x28,%rsp
33bc: 31 c0 xor %eax,%eax
if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip)))
return false;
/* Don't migrate static entries, drop packets */
if (f->state & NUD_NOARP)
33be: 5b pop %rbx
33bf: 41 5c pop %r12
33c1: 41 5d pop %r13
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}
return false;
}
33c3: 41 5e pop %r14
33c5: 41 5f pop %r15
33c7: 5d pop %rbp
33c8: c3 retq
33c9: 49 8b 51 e0 mov -0x20(%r9),%rdx
33cd: 49 8b 41 e8 mov -0x18(%r9),%rax
33d1: 49 33 54 24 08 xor 0x8(%r12),%rdx
static inline
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
{
if (a->sa.sa_family != b->sa.sa_family)
return false;
if (a->sa.sa_family == AF_INET6)
33d6: 49 33 44 24 10 xor 0x10(%r12),%rax
return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
else
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
33db: 48 09 c2 or %rax,%rdx
33de: 0f 94 c0 sete %al
33e1: eb d1 jmp 33b4 <vxlan_snoop+0x84>
33e3: 49 8d 9d 28 09 00 00 lea 0x928(%r13),%rbx
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}
return false;
}
33ea: 48 89 df mov %rbx,%rdi
f = vxlan_find_mac(vxlan, src_mac);
if (likely(f)) {
struct vxlan_rdst *rdst = first_remote_rcu(f);
if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip)))
return false;
33ed: e8 00 00 00 00 callq 33f2 <vxlan_snoop+0xc2>
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}
return false;
}
33f2: 49 8b 45 48 mov 0x48(%r13),%rax
33f6: a8 01 test $0x1,%al
33f8: 0f 85 a0 00 00 00 jne 349e <vxlan_snoop+0x16e>
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul1 = (const unsigned long *)a1;
const unsigned long *ul2 = (const unsigned long *)a2;
return ((ul1[0] ^ ul2[0]) | (ul1[1] ^ ul2[1])) == 0UL;
33fe: 48 89 df mov %rbx,%rdi
3401: ff 14 25 00 00 00 00 callq *0x0
3408: 48 83 c4 28 add $0x28,%rsp
340c: 31 c0 xor %eax,%eax
340e: 5b pop %rbx
340f: 41 5c pop %r12
3411: 41 5d pop %r13
raw_spin_lock_init(&(_lock)->rlock); \
} while (0)
static __always_inline void spin_lock(spinlock_t *lock)
{
raw_spin_lock(&lock->rlock);
3413: 41 5e pop %r14
3415: 41 5f pop %r15
3417: 5d pop %rbp
3418: c3 retq
3419: 4c 89 4d d0 mov %r9,-0x30(%rbp)
341d: e8 00 00 00 00 callq 3422 <vxlan_snoop+0xf2>
3422: 4c 8b 4d d0 mov -0x30(%rbp),%r9
} else {
/* learned new entry */
spin_lock(&vxlan->hash_lock);
/* close off race between vxlan_flush and incoming packets */
if (netif_running(dev))
3426: 85 c0 test %eax,%eax
3428: 4d 8d 51 d8 lea -0x28(%r9),%r10
342c: 74 28 je 3456 <vxlan_snoop+0x126>
342e: 4c 89 d1 mov %r10,%rcx
3431: 4d 89 e0 mov %r12,%r8
3434: 4c 89 fa mov %r15,%rdx
3437: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}
return false;
}
343e: 4c 89 ef mov %r13,%rdi
3441: 4c 89 4d c8 mov %r9,-0x38(%rbp)
3445: 4c 89 55 d0 mov %r10,-0x30(%rbp)
3449: e8 00 00 00 00 callq 344e <vxlan_snoop+0x11e>
/* Don't migrate static entries, drop packets */
if (f->state & NUD_NOARP)
return true;
if (net_ratelimit())
344e: 4c 8b 4d c8 mov -0x38(%rbp),%r9
3452: 4c 8b 55 d0 mov -0x30(%rbp),%r10
3456: 49 8b 04 24 mov (%r12),%rax
345a: b9 1c 00 00 00 mov $0x1c,%ecx
netdev_info(dev,
345f: 4c 89 d2 mov %r10,%rdx
3462: 48 89 de mov %rbx,%rsi
3465: 4c 89 f7 mov %r14,%rdi
3468: 49 89 41 d8 mov %rax,-0x28(%r9)
346c: 49 8b 44 24 08 mov 0x8(%r12),%rax
3471: 49 89 41 e0 mov %rax,-0x20(%r9)
3475: 49 8b 44 24 10 mov 0x10(%r12),%rax
347a: 49 89 41 e8 mov %rax,-0x18(%r9)
347e: 41 8b 44 24 18 mov 0x18(%r12),%eax
3483: 41 89 41 f0 mov %eax,-0x10(%r9)
"%pM migrated from %pIS to %pIS\n",
src_mac, &rdst->remote_ip.sa, &src_ip->sa);
rdst->remote_ip = *src_ip;
3487: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 348e <vxlan_snoop+0x15e>
f->updated = jiffies;
vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH);
348e: 48 89 43 20 mov %rax,0x20(%rbx)
3492: e8 a9 e8 ff ff callq 1d40 <vxlan_fdb_notify>
3497: 31 c0 xor %eax,%eax
if (net_ratelimit())
netdev_info(dev,
"%pM migrated from %pIS to %pIS\n",
src_mac, &rdst->remote_ip.sa, &src_ip->sa);
rdst->remote_ip = *src_ip;
3499: e9 f5 fe ff ff jmpq 3393 <vxlan_snoop+0x63>
349e: 45 0f b7 8d 7c 09 00 movzwl 0x97c(%r13),%r9d
34a5: 00
34a6: c7 44 24 10 02 00 00 movl $0x2,0x10(%rsp)
34ad: 00
34ae: 41 b8 00 06 00 00 mov $0x600,%r8d
34b4: c7 44 24 08 00 00 00 movl $0x0,0x8(%rsp)
34bb: 00
f->updated = jiffies;
34bc: 41 8b 85 a0 08 00 00 mov 0x8a0(%r13),%eax
vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH);
34c3: b9 02 00 00 00 mov $0x2,%ecx
vxlan->default_dst.remote_vni,
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}
return false;
34c8: 4c 89 e2 mov %r12,%rdx
34cb: 4c 89 fe mov %r15,%rsi
/* learned new entry */
spin_lock(&vxlan->hash_lock);
/* close off race between vxlan_flush and incoming packets */
if (netif_running(dev))
vxlan_fdb_create(vxlan, src_mac, src_ip,
34ce: 4c 89 f7 mov %r14,%rdi
34d1: 89 04 24 mov %eax,(%rsp)
34d4: e8 b7 f0 ff ff callq 2590 <vxlan_fdb_create>
34d9: e9 20 ff ff ff jmpq 33fe <vxlan_snoop+0xce>
34de: 66 90 xchg %ax,%ax
00000000000034e0 <vxlan_fdb_add>:
34e0: e8 00 00 00 00 callq 34e5 <vxlan_fdb_add+0x5>
34e5: 55 push %rbp
34e6: 48 89 e5 mov %rsp,%rbp
34e9: 41 57 push %r15
34eb: 41 56 push %r14
34ed: 41 55 push %r13
34ef: 41 54 push %r12
34f1: 49 89 ff mov %rdi,%r15
34f4: 53 push %rbx
34f5: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
34f9: 48 83 ec 58 sub $0x58,%rsp
34fd: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
3504: 00 00
3506: 48 89 44 24 50 mov %rax,0x50(%rsp)
350b: 31 c0 xor %eax,%eax
350d: 0f b7 47 08 movzwl 0x8(%rdi),%eax
/* Add static entry (via netlink) */
static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid, u16 flags)
{
3511: a8 82 test $0x82,%al
3513: 0f 84 cb 00 00 00 je 35e4 <vxlan_fdb_add+0x104>
3519: 48 83 7e 08 00 cmpq $0x0,0x8(%rsi)
351e: 48 89 f7 mov %rsi,%rdi
3521: 0f 84 b6 00 00 00 je 35dd <vxlan_fdb_add+0xfd>
3527: 4c 8d a2 40 08 00 00 lea 0x840(%rdx),%r12
352e: 48 89 d3 mov %rdx,%rbx
3531: 49 89 cd mov %rcx,%r13
3534: 45 89 ce mov %r9d,%r14d
3537: 4c 8d 44 24 20 lea 0x20(%rsp),%r8
353c: 4c 8d 4c 24 24 lea 0x24(%rsp),%r9
__be16 port;
__be32 vni;
u32 ifindex;
int err;
if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
3541: 48 8d 4c 24 1e lea 0x1e(%rsp),%rcx
3546: 48 8d 54 24 28 lea 0x28(%rsp),%rdx
pr_info("RTM_NEWNEIGH with invalid state %#x\n",
ndm->ndm_state);
return -EINVAL;
}
if (tb[NDA_DST] == NULL)
354b: 4c 89 e6 mov %r12,%rsi
354e: e8 cd d0 ff ff callq 620 <vxlan_fdb_parse>
3553: 85 c0 test %eax,%eax
3555: 75 67 jne 35be <vxlan_fdb_add+0xde>
3557: 0f b7 74 24 28 movzwl 0x28(%rsp),%esi
355c: b8 9f ff ff ff mov $0xffffff9f,%eax
3561: 66 39 b3 80 08 00 00 cmp %si,0x880(%rbx)
return -EINVAL;
err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
3568: 75 54 jne 35be <vxlan_fdb_add+0xde>
356a: 48 81 c3 28 09 00 00 add $0x928,%rbx
3571: 48 89 df mov %rbx,%rdi
3574: e8 00 00 00 00 callq 3579 <vxlan_fdb_add+0x99>
3579: 41 0f b6 47 0a movzbl 0xa(%r15),%eax
357e: 44 0f b7 4c 24 1e movzwl 0x1e(%rsp),%r9d
if (err)
3584: 48 8d 54 24 28 lea 0x28(%rsp),%rdx
return err;
if (vxlan->default_dst.remote_ip.sa.sa_family != ip.sa.sa_family)
3589: 41 0f b7 4f 08 movzwl 0x8(%r15),%ecx
return -EAFNOSUPPORT;
358e: 4c 89 e7 mov %r12,%rdi
err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
if (err)
return err;
if (vxlan->default_dst.remote_ip.sa.sa_family != ip.sa.sa_family)
3591: 45 0f b7 c6 movzwl %r14w,%r8d
3595: 4c 89 ee mov %r13,%rsi
3598: 89 44 24 10 mov %eax,0x10(%rsp)
}
static __always_inline void spin_lock_bh(spinlock_t *lock)
{
raw_spin_lock_bh(&lock->rlock);
359c: 8b 44 24 24 mov 0x24(%rsp),%eax
35a0: 89 44 24 08 mov %eax,0x8(%rsp)
35a4: 8b 44 24 20 mov 0x20(%rsp),%eax
35a8: 89 04 24 mov %eax,(%rsp)
return -EAFNOSUPPORT;
spin_lock_bh(&vxlan->hash_lock);
err = vxlan_fdb_create(vxlan, addr, &ip, ndm->ndm_state, flags,
35ab: e8 e0 ef ff ff callq 2590 <vxlan_fdb_create>
35b0: 48 89 df mov %rbx,%rdi
35b3: 41 89 c4 mov %eax,%r12d
35b6: e8 00 00 00 00 callq 35bb <vxlan_fdb_add+0xdb>
35bb: 44 89 e0 mov %r12d,%eax
35be: 48 8b 74 24 50 mov 0x50(%rsp),%rsi
35c3: 65 48 33 34 25 28 00 xor %gs:0x28,%rsi
35ca: 00 00
35cc: 75 2c jne 35fa <vxlan_fdb_add+0x11a>
35ce: 48 8d 65 d8 lea -0x28(%rbp),%rsp
35d2: 5b pop %rbx
35d3: 41 5c pop %r12
35d5: 41 5d pop %r13
35d7: 41 5e pop %r14
35d9: 41 5f pop %r15
35db: 5d pop %rbp
35dc: c3 retq
35dd: b8 ea ff ff ff mov $0xffffffea,%eax
raw_spin_unlock(&lock->rlock);
}
static __always_inline void spin_unlock_bh(spinlock_t *lock)
{
raw_spin_unlock_bh(&lock->rlock);
35e2: eb da jmp 35be <vxlan_fdb_add+0xde>
35e4: 0f b7 f0 movzwl %ax,%esi
35e7: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
port, vni, ifindex, ndm->ndm_flags);
spin_unlock_bh(&vxlan->hash_lock);
return err;
}
35ee: e8 00 00 00 00 callq 35f3 <vxlan_fdb_add+0x113>
35f3: b8 ea ff ff ff mov $0xffffffea,%eax
35f8: eb c4 jmp 35be <vxlan_fdb_add+0xde>
35fa: e8 00 00 00 00 callq 35ff <vxlan_fdb_add+0x11f>
35ff: 90 nop
0000000000003600 <vxlan_get_route>:
3600: e8 00 00 00 00 callq 3605 <vxlan_get_route+0x5>
3605: 55 push %rbp
3606: 48 89 e5 mov %rsp,%rbp
3609: 41 57 push %r15
360b: 41 56 push %r14
ndm->ndm_state);
return -EINVAL;
}
if (tb[NDA_DST] == NULL)
return -EINVAL;
360d: 41 55 push %r13
360f: 41 54 push %r12
3611: 4d 89 cc mov %r9,%r12
__be32 vni;
u32 ifindex;
int err;
if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
pr_info("RTM_NEWNEIGH with invalid state %#x\n",
3614: 53 push %rbx
3615: 89 cb mov %ecx,%ebx
3617: 49 89 ff mov %rdi,%r15
361a: 48 83 ec 48 sub $0x48,%rsp
361e: 44 8b 8e b4 00 00 00 mov 0xb4(%rsi),%r9d
ndm->ndm_state);
return -EINVAL;
3625: 4c 8b 6d 10 mov 0x10(%rbp),%r13
3629: 65 48 8b 0c 25 28 00 mov %gs:0x28,%rcx
3630: 00 00
static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan,
struct sk_buff *skb, int oif, u8 tos,
__be32 daddr, __be32 *saddr,
struct dst_cache *dst_cache,
const struct ip_tunnel_info *info)
{
3632: 48 89 4d d0 mov %rcx,-0x30(%rbp)
3636: 31 c9 xor %ecx,%ecx
3638: 48 8b 45 18 mov 0x18(%rbp),%rax
363c: 45 85 c9 test %r9d,%r9d
363f: 75 56 jne 3697 <vxlan_get_route+0x97>
3641: 48 85 c0 test %rax,%rax
3644: 49 89 f6 mov %rsi,%r14
3647: 74 4a je 3693 <vxlan_get_route+0x93>
3649: f6 40 28 20 testb $0x20,0x28(%rax)
364d: 75 48 jne 3697 <vxlan_get_route+0x97>
364f: 4c 89 e6 mov %r12,%rsi
3652: 4c 89 ef mov %r13,%rdi
3655: 44 89 45 94 mov %r8d,-0x6c(%rbp)
3659: 89 55 98 mov %edx,-0x68(%rbp)
365c: e8 00 00 00 00 callq 3661 <vxlan_get_route+0x61>
3661: 48 85 c0 test %rax,%rax
3664: 8b 55 98 mov -0x68(%rbp),%edx
3667: 44 8b 45 94 mov -0x6c(%rbp),%r8d
366b: 0f 84 8d 00 00 00 je 36fe <vxlan_get_route+0xfe>
ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
if (skb->mark)
return false;
if (!info)
3671: 48 8b 5d d0 mov -0x30(%rbp),%rbx
3675: 65 48 33 1c 25 28 00 xor %gs:0x28,%rbx
367c: 00 00
return true;
if (info->key.tun_flags & TUNNEL_NOCACHE)
367e: 0f 85 89 00 00 00 jne 370d <vxlan_get_route+0x10d>
struct flowi4 fl4;
if (tos && !info)
use_cache = false;
if (use_cache) {
rt = dst_cache_get_ip4(dst_cache, saddr);
3684: 48 83 c4 48 add $0x48,%rsp
3688: 5b pop %rbx
3689: 41 5c pop %r12
368b: 41 5d pop %r13
368d: 41 5e pop %r14
368f: 41 5f pop %r15
if (rt)
3691: 5d pop %rbp
3692: c3 retq
3693: 84 db test %bl,%bl
3695: 74 b8 je 364f <vxlan_get_route+0x4f>
3697: 45 31 f6 xor %r14d,%r14d
369a: 48 8d 75 a0 lea -0x60(%rbp),%rsi
369e: 31 c0 xor %eax,%eax
36a0: b9 06 00 00 00 mov $0x6,%ecx
*saddr = fl4.saddr;
if (use_cache)
dst_cache_set_ip4(dst_cache, &rt->dst, fl4.saddr);
}
return rt;
}
36a5: 83 e3 1e and $0x1e,%ebx
36a8: 48 89 f7 mov %rsi,%rdi
36ab: f3 48 ab rep stos %rax,%es:(%rdi)
36ae: 41 8b 04 24 mov (%r12),%eax
36b2: 49 8b 7f 38 mov 0x38(%r15),%rdi
36b6: 89 55 a0 mov %edx,-0x60(%rbp)
36b9: 31 d2 xor %edx,%edx
36bb: 88 5d ac mov %bl,-0x54(%rbp)
36be: 44 89 4d a8 mov %r9d,-0x58(%rbp)
36c2: c6 45 ae 11 movb $0x11,-0x52(%rbp)
{
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
struct rtable *rt = NULL;
struct flowi4 fl4;
if (tos && !info)
36c6: 44 89 45 c4 mov %r8d,-0x3c(%rbp)
rt = dst_cache_get_ip4(dst_cache, saddr);
if (rt)
return rt;
}
memset(&fl4, 0, sizeof(fl4));
36ca: 89 45 c0 mov %eax,-0x40(%rbp)
36cd: e8 00 00 00 00 callq 36d2 <vxlan_get_route+0xd2>
36d2: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
36d8: 77 97 ja 3671 <vxlan_get_route+0x71>
36da: 8b 55 c0 mov -0x40(%rbp),%edx
36dd: 45 84 f6 test %r14b,%r14b
fl4.flowi4_oif = oif;
fl4.flowi4_tos = RT_TOS(tos);
fl4.flowi4_mark = skb->mark;
fl4.flowi4_proto = IPPROTO_UDP;
fl4.daddr = daddr;
fl4.saddr = *saddr;
36e0: 41 89 14 24 mov %edx,(%r12)
struct dst_entry *ipv4_blackhole_route(struct net *net,
struct dst_entry *dst_orig);
static inline struct rtable *ip_route_output_key(struct net *net, struct flowi4 *flp)
{
return ip_route_output_flow(net, flp, NULL);
36e4: 74 8b je 3671 <vxlan_get_route+0x71>
if (rt)
return rt;
}
memset(&fl4, 0, sizeof(fl4));
fl4.flowi4_oif = oif;
36e6: 48 89 c6 mov %rax,%rsi
36e9: 4c 89 ef mov %r13,%rdi
fl4.flowi4_tos = RT_TOS(tos);
36ec: 48 89 45 98 mov %rax,-0x68(%rbp)
fl4.flowi4_mark = skb->mark;
36f0: e8 00 00 00 00 callq 36f5 <vxlan_get_route+0xf5>
fl4.flowi4_proto = IPPROTO_UDP;
36f5: 48 8b 45 98 mov -0x68(%rbp),%rax
fl4.daddr = daddr;
36f9: e9 73 ff ff ff jmpq 3671 <vxlan_get_route+0x71>
36fe: 45 8b 8e b4 00 00 00 mov 0xb4(%r14),%r9d
fl4.saddr = *saddr;
rt = ip_route_output_key(vxlan->net, &fl4);
if (!IS_ERR(rt)) {
3705: 41 be 01 00 00 00 mov $0x1,%r14d
*saddr = fl4.saddr;
370b: eb 8d jmp 369a <vxlan_get_route+0x9a>
if (use_cache)
370d: e8 00 00 00 00 callq 3712 <vxlan_get_route+0x112>
fl4.daddr = daddr;
fl4.saddr = *saddr;
rt = ip_route_output_key(vxlan->net, &fl4);
if (!IS_ERR(rt)) {
*saddr = fl4.saddr;
3712: 0f 1f 40 00 nopl 0x0(%rax)
if (use_cache)
dst_cache_set_ip4(dst_cache, &rt->dst, fl4.saddr);
3716: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
371d: 00 00 00
0000000000003720 <vxlan_stop>:
3720: e8 00 00 00 00 callq 3725 <vxlan_stop+0x5>
3725: 55 push %rbp
3726: 48 89 e5 mov %rsp,%rbp
3729: 41 57 push %r15
372b: 41 56 push %r14
372d: 41 55 push %r13
372f: 41 54 push %r12
3731: 49 89 fe mov %rdi,%r14
3734: 53 push %rbx
if (tos && !info)
use_cache = false;
if (use_cache) {
rt = dst_cache_get_ip4(dst_cache, saddr);
if (rt)
3735: 4c 8d a7 40 08 00 00 lea 0x840(%rdi),%r12
373c: 48 83 ec 28 sub $0x28,%rsp
*saddr = fl4.saddr;
if (use_cache)
dst_cache_set_ip4(dst_cache, &rt->dst, fl4.saddr);
}
return rt;
}
3740: 0f b7 b7 80 08 00 00 movzwl 0x880(%rdi),%esi
3747: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
374e: 00 00
spin_unlock_bh(&vxlan->hash_lock);
}
/* Cleanup timer and forwarding table on shutdown */
static int vxlan_stop(struct net_device *dev)
{
3750: 48 89 45 d0 mov %rax,-0x30(%rbp)
3754: 31 c0 xor %eax,%eax
3756: 48 8b 87 78 08 00 00 mov 0x878(%rdi),%rax
375d: 48 8b 90 88 14 00 00 mov 0x1488(%rax),%rdx
3764: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 376a <vxlan_stop+0x4a>
376a: 83 e8 01 sub $0x1,%eax
376d: 66 83 fe 0a cmp $0xa,%si
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
}
static inline bool vxlan_addr_multicast(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
3771: 48 98 cltq
3773: 48 8b 4c c2 18 mov 0x18(%rdx,%rax,8),%rcx
spin_unlock_bh(&vxlan->hash_lock);
}
/* Cleanup timer and forwarding table on shutdown */
static int vxlan_stop(struct net_device *dev)
{
3778: 0f 84 c4 00 00 00 je 3842 <vxlan_stop+0x122>
377e: 8b bf 84 08 00 00 mov 0x884(%rdi),%edi
3784: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%rbp)
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
378b: 89 f8 mov %edi,%eax
378d: 25 f0 00 00 00 and $0xf0,%eax
3792: 3d e0 00 00 00 cmp $0xe0,%eax
3797: 0f 84 c3 00 00 00 je 3860 <vxlan_stop+0x140>
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
}
static inline bool vxlan_addr_multicast(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
379d: 49 8d be e0 08 00 00 lea 0x8e0(%r14),%rdi
37a4: 49 8d 9e a0 09 00 00 lea 0x9a0(%r14),%rbx
37ab: 4d 8d ae a0 11 00 00 lea 0x11a0(%r14),%r13
return ipv6_addr_is_multicast(&ipa->sin6.sin6_addr);
else
return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
37b2: e8 00 00 00 00 callq 37b7 <vxlan_stop+0x97>
/* Cleanup timer and forwarding table on shutdown */
static int vxlan_stop(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
int ret = 0;
37b7: 49 8d 86 28 09 00 00 lea 0x928(%r14),%rax
if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip) &&
37be: 48 89 c7 mov %rax,%rdi
37c1: 48 89 45 b0 mov %rax,-0x50(%rbp)
37c5: e8 00 00 00 00 callq 37ca <vxlan_stop+0xaa>
37ca: 48 8b 33 mov (%rbx),%rsi
!vxlan_group_used(vn, vxlan))
ret = vxlan_igmp_leave(vxlan);
del_timer_sync(&vxlan->age_timer);
37cd: 48 85 f6 test %rsi,%rsi
37d0: 75 0a jne 37dc <vxlan_stop+0xbc>
37d2: eb 24 jmp 37f8 <vxlan_stop+0xd8>
37d4: 4d 85 ff test %r15,%r15
37d7: 4c 89 fe mov %r15,%rsi
37da: 74 1c je 37f8 <vxlan_stop+0xd8>
37dc: 0f b7 56 44 movzwl 0x44(%rsi),%edx
37e0: 4c 8b 3e mov (%rsi),%r15
37e3: 0b 56 40 or 0x40(%rsi),%edx
37e6: 74 ec je 37d4 <vxlan_stop+0xb4>
raw_spin_lock(&lock->rlock);
}
static __always_inline void spin_lock_bh(spinlock_t *lock)
{
raw_spin_lock_bh(&lock->rlock);
37e8: 4c 89 e7 mov %r12,%rdi
37eb: e8 40 e6 ff ff callq 1e30 <vxlan_fdb_destroy>
37f0: 4d 85 ff test %r15,%r15
37f3: 4c 89 fe mov %r15,%rsi
37f6: 75 e4 jne 37dc <vxlan_stop+0xbc>
37f8: 48 83 c3 08 add $0x8,%rbx
unsigned int h;
spin_lock_bh(&vxlan->hash_lock);
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct hlist_node *p, *n;
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
37fc: 4c 39 eb cmp %r13,%rbx
37ff: 75 c9 jne 37ca <vxlan_stop+0xaa>
3801: 48 8b 7d b0 mov -0x50(%rbp),%rdi
3805: e8 00 00 00 00 callq 380a <vxlan_stop+0xea>
380a: 49 8d b6 68 08 00 00 lea 0x868(%r14),%rsi
3811: 49 8d be 60 08 00 00 lea 0x860(%r14),%rdi
struct vxlan_fdb *f
= container_of(p, struct vxlan_fdb, hlist);
/* the all_zeros_mac entry is deleted at vxlan_uninit */
if (!is_zero_ether_addr(f->eth_addr))
vxlan_fdb_destroy(vxlan, f);
3818: e8 73 d4 ff ff callq c90 <vxlan_sock_release.isra.44>
381d: 48 8b 4d d0 mov -0x30(%rbp),%rcx
unsigned int h;
spin_lock_bh(&vxlan->hash_lock);
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct hlist_node *p, *n;
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
3821: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
3828: 00 00
382a: 8b 45 bc mov -0x44(%rbp),%eax
static void vxlan_flush(struct vxlan_dev *vxlan)
{
unsigned int h;
spin_lock_bh(&vxlan->hash_lock);
for (h = 0; h < FDB_HASH_SIZE; ++h) {
382d: 0f 85 f0 01 00 00 jne 3a23 <vxlan_stop+0x303>
raw_spin_unlock(&lock->rlock);
}
static __always_inline void spin_unlock_bh(spinlock_t *lock)
{
raw_spin_unlock_bh(&lock->rlock);
3833: 48 83 c4 28 add $0x28,%rsp
3837: 5b pop %rbx
3838: 41 5c pop %r12
383a: 41 5d pop %r13
383c: 41 5e pop %r14
383e: 41 5f pop %r15
3840: 5d pop %rbp
3841: c3 retq
3842: 0f b6 87 88 08 00 00 movzbl 0x888(%rdi),%eax
ret = vxlan_igmp_leave(vxlan);
del_timer_sync(&vxlan->age_timer);
vxlan_flush(vxlan);
vxlan_sock_release(vxlan);
3849: 3d ff 00 00 00 cmp $0xff,%eax
return ret;
}
384e: 0f 84 92 01 00 00 je 39e6 <vxlan_stop+0x2c6>
3854: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%rbp)
385b: e9 3d ff ff ff jmpq 379d <vxlan_stop+0x7d>
3860: 66 83 fe 02 cmp $0x2,%si
3864: 0f 84 12 01 00 00 je 397c <vxlan_stop+0x25c>
386a: 48 8b 11 mov (%rcx),%rdx
386d: 48 39 d1 cmp %rdx,%rcx
3870: 48 8d 42 f0 lea -0x10(%rdx),%rax
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
int ret = 0;
if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip) &&
3874: 0f 84 96 01 00 00 je 3a10 <vxlan_stop+0x2f0>
387a: 41 8b 9e a4 08 00 00 mov 0x8a4(%r14),%ebx
3881: eb 21 jmp 38a4 <vxlan_stop+0x184>
3883: 66 83 fe 0a cmp $0xa,%si
/* Cleanup timer and forwarding table on shutdown */
static int vxlan_stop(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
int ret = 0;
3887: 0f 84 92 00 00 00 je 391f <vxlan_stop+0x1ff>
388d: 66 3b 70 40 cmp 0x40(%rax),%si
unsigned short family = dev->default_dst.remote_ip.sa.sa_family;
/* The vxlan_sock is only used by dev, leaving group has
* no effect on other vxlan devices.
*/
if (family == AF_INET && dev->vn4_sock &&
3891: 0f 84 c2 00 00 00 je 3959 <vxlan_stop+0x239>
3897: 48 8b 50 10 mov 0x10(%rax),%rdx
if (family == AF_INET6 && dev->vn6_sock &&
atomic_read(&dev->vn6_sock->refcnt) == 1)
return false;
#endif
list_for_each_entry(vxlan, &vn->vxlan_list, next) {
389b: 48 39 d1 cmp %rdx,%rcx
389e: 48 8d 42 f0 lea -0x10(%rdx),%rax
38a2: 74 32 je 38d6 <vxlan_stop+0x1b6>
38a4: 48 8b 50 30 mov 0x30(%rax),%rdx
38a8: 48 8b 52 48 mov 0x48(%rdx),%rdx
38ac: 83 e2 01 and $0x1,%edx
38af: 74 e6 je 3897 <vxlan_stop+0x177>
38b1: 49 39 c4 cmp %rax,%r12
continue;
if (family == AF_INET && vxlan->vn4_sock != dev->vn4_sock)
continue;
#if IS_ENABLED(CONFIG_IPV6)
if (family == AF_INET6 && vxlan->vn6_sock != dev->vn6_sock)
38b4: 74 e1 je 3897 <vxlan_stop+0x177>
38b6: 66 83 fe 02 cmp $0x2,%si
38ba: 75 c7 jne 3883 <vxlan_stop+0x163>
38bc: 49 8b be 60 08 00 00 mov 0x860(%r14),%rdi
#if IS_ENABLED(CONFIG_IPV6)
static inline
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
{
if (a->sa.sa_family != b->sa.sa_family)
38c3: 48 39 78 20 cmp %rdi,0x20(%rax)
if (family == AF_INET6 && dev->vn6_sock &&
atomic_read(&dev->vn6_sock->refcnt) == 1)
return false;
#endif
list_for_each_entry(vxlan, &vn->vxlan_list, next) {
38c7: 74 c4 je 388d <vxlan_stop+0x16d>
38c9: 48 8b 50 10 mov 0x10(%rax),%rdx
38cd: 48 39 d1 cmp %rdx,%rcx
38d0: 48 8d 42 f0 lea -0x10(%rdx),%rax
if (!netif_running(vxlan->dev) || vxlan == dev)
38d4: 75 ce jne 38a4 <vxlan_stop+0x184>
38d6: 66 83 fe 02 cmp $0x2,%si
38da: 0f 84 48 01 00 00 je 3a28 <vxlan_stop+0x308>
38e0: 49 8b 86 68 08 00 00 mov 0x868(%r14),%rax
continue;
if (family == AF_INET && vxlan->vn4_sock != dev->vn4_sock)
38e7: 48 8b 40 10 mov 0x10(%rax),%rax
38eb: 31 f6 xor %esi,%esi
38ed: 4c 8b 68 20 mov 0x20(%rax),%r13
38f1: 4c 89 ef mov %r13,%rdi
38f4: e8 00 00 00 00 callq 38f9 <vxlan_stop+0x1d9>
if (family == AF_INET6 && dev->vn6_sock &&
atomic_read(&dev->vn6_sock->refcnt) == 1)
return false;
#endif
list_for_each_entry(vxlan, &vn->vxlan_list, next) {
38f9: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 3900 <vxlan_stop+0x1e0>
3900: 4c 89 ef mov %r13,%rdi
3903: 49 8d 96 88 08 00 00 lea 0x888(%r14),%rdx
struct sock *sk;
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
int ret = -EINVAL;
if (ip->sa.sa_family == AF_INET) {
390a: 89 de mov %ebx,%esi
390c: ff 50 08 callq *0x8(%rax)
390f: 4c 89 ef mov %r13,%rdi
3912: 89 45 bc mov %eax,-0x44(%rbp)
3915: e8 00 00 00 00 callq 391a <vxlan_stop+0x1fa>
lock_sock(sk);
ret = ip_mc_leave_group(sk, &mreq);
release_sock(sk);
#if IS_ENABLED(CONFIG_IPV6)
} else {
sk = vxlan->vn6_sock->sock->sk;
391a: e9 7e fe ff ff jmpq 379d <vxlan_stop+0x7d>
391f: 49 8b be 68 08 00 00 mov 0x868(%r14),%rdi
3926: 48 39 78 28 cmp %rdi,0x28(%rax)
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
392a: 0f 85 67 ff ff ff jne 3897 <vxlan_stop+0x177>
3930: 66 83 78 40 0a cmpw $0xa,0x40(%rax)
&ip->sin6.sin6_addr);
3935: 0f 85 5c ff ff ff jne 3897 <vxlan_stop+0x177>
release_sock(sk);
#if IS_ENABLED(CONFIG_IPV6)
} else {
sk = vxlan->vn6_sock->sock->sk;
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
393b: 48 8b 78 48 mov 0x48(%rax),%rdi
&ip->sin6.sin6_addr);
release_sock(sk);
393f: 48 8b 50 50 mov 0x50(%rax),%rdx
release_sock(sk);
#if IS_ENABLED(CONFIG_IPV6)
} else {
sk = vxlan->vn6_sock->sock->sk;
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
3943: 49 33 be 88 08 00 00 xor 0x888(%r14),%rdi
&ip->sin6.sin6_addr);
release_sock(sk);
394a: 49 33 96 90 08 00 00 xor 0x890(%r14),%rdx
continue;
if (family == AF_INET && vxlan->vn4_sock != dev->vn4_sock)
continue;
#if IS_ENABLED(CONFIG_IPV6)
if (family == AF_INET6 && vxlan->vn6_sock != dev->vn6_sock)
3951: 48 09 d7 or %rdx,%rdi
3954: 0f 94 c2 sete %dl
3957: eb 0d jmp 3966 <vxlan_stop+0x246>
3959: 41 8b be 84 08 00 00 mov 0x884(%r14),%edi
#if IS_ENABLED(CONFIG_IPV6)
static inline
bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)
{
if (a->sa.sa_family != b->sa.sa_family)
3960: 39 78 44 cmp %edi,0x44(%rax)
3963: 0f 94 c2 sete %dl
3966: 84 d2 test %dl,%dl
3968: 0f 84 29 ff ff ff je 3897 <vxlan_stop+0x177>
396e: 39 58 64 cmp %ebx,0x64(%rax)
3971: 0f 85 20 ff ff ff jne 3897 <vxlan_stop+0x177>
3977: e9 d8 fe ff ff jmpq 3854 <vxlan_stop+0x134>
397c: 49 8b 96 60 08 00 00 mov 0x860(%r14),%rdx
3983: 48 85 d2 test %rdx,%rdx
3986: 74 0b je 3993 <vxlan_stop+0x273>
3988: 8b 82 18 20 00 00 mov 0x2018(%rdx),%eax
return false;
if (a->sa.sa_family == AF_INET6)
return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
else
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
398e: 83 f8 01 cmp $0x1,%eax
3991: 74 10 je 39a3 <vxlan_stop+0x283>
3993: 4c 8b 01 mov (%rcx),%r8
#if IS_ENABLED(CONFIG_IPV6)
if (family == AF_INET6 && vxlan->vn6_sock != dev->vn6_sock)
continue;
#endif
if (!vxlan_addr_equal(&vxlan->default_dst.remote_ip,
3996: 4c 39 c1 cmp %r8,%rcx
3999: 49 8d 40 f0 lea -0x10(%r8),%rax
399d: 0f 85 d7 fe ff ff jne 387a <vxlan_stop+0x15a>
&dev->default_dst.remote_ip))
continue;
if (vxlan->default_dst.remote_ifindex !=
39a3: 41 8b 9e a4 08 00 00 mov 0x8a4(%r14),%ebx
39aa: 48 8b 42 10 mov 0x10(%rdx),%rax
unsigned short family = dev->default_dst.remote_ip.sa.sa_family;
/* The vxlan_sock is only used by dev, leaving group has
* no effect on other vxlan devices.
*/
if (family == AF_INET && dev->vn4_sock &&
39ae: 89 5d cc mov %ebx,-0x34(%rbp)
39b1: 31 f6 xor %esi,%esi
39b3: 48 c7 45 c4 00 00 00 movq $0x0,-0x3c(%rbp)
39ba: 00
39bb: 89 7d c4 mov %edi,-0x3c(%rbp)
39be: 48 8b 58 20 mov 0x20(%rax),%rbx
39c2: 48 89 df mov %rbx,%rdi
if (family == AF_INET6 && dev->vn6_sock &&
atomic_read(&dev->vn6_sock->refcnt) == 1)
return false;
#endif
list_for_each_entry(vxlan, &vn->vxlan_list, next) {
39c5: e8 00 00 00 00 callq 39ca <vxlan_stop+0x2aa>
39ca: 48 8d 75 c4 lea -0x3c(%rbp),%rsi
39ce: 48 89 df mov %rbx,%rdi
39d1: e8 00 00 00 00 callq 39d6 <vxlan_stop+0x2b6>
/* Inverse of vxlan_igmp_join when last VNI is brought down */
static int vxlan_igmp_leave(struct vxlan_dev *vxlan)
{
struct sock *sk;
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
39d6: 48 89 df mov %rbx,%rdi
39d9: 89 45 bc mov %eax,-0x44(%rbp)
struct ip_mreqn mreq = {
.imr_multiaddr.s_addr = ip->sin.sin_addr.s_addr,
.imr_ifindex = ifindex,
};
sk = vxlan->vn4_sock->sock->sk;
39dc: e8 00 00 00 00 callq 39e1 <vxlan_stop+0x2c1>
39e1: e9 b7 fd ff ff jmpq 379d <vxlan_stop+0x7d>
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
int ret = -EINVAL;
if (ip->sa.sa_family == AF_INET) {
struct ip_mreqn mreq = {
39e6: 48 8b 87 68 08 00 00 mov 0x868(%rdi),%rax
39ed: 48 85 c0 test %rax,%rax
.imr_multiaddr.s_addr = ip->sin.sin_addr.s_addr,
.imr_ifindex = ifindex,
};
sk = vxlan->vn4_sock->sock->sk;
39f0: 0f 84 74 fe ff ff je 386a <vxlan_stop+0x14a>
39f6: 8b 90 18 20 00 00 mov 0x2018(%rax),%edx
lock_sock(sk);
ret = ip_mc_leave_group(sk, &mreq);
39fc: 83 fa 01 cmp $0x1,%edx
39ff: 0f 85 65 fe ff ff jne 386a <vxlan_stop+0x14a>
3a05: 8b 9f a4 08 00 00 mov 0x8a4(%rdi),%ebx
3a0b: e9 d7 fe ff ff jmpq 38e7 <vxlan_stop+0x1c7>
release_sock(sk);
3a10: 41 8b 9e a4 08 00 00 mov 0x8a4(%r14),%ebx
*/
if (family == AF_INET && dev->vn4_sock &&
atomic_read(&dev->vn4_sock->refcnt) == 1)
return false;
#if IS_ENABLED(CONFIG_IPV6)
if (family == AF_INET6 && dev->vn6_sock &&
3a17: 49 8b 86 68 08 00 00 mov 0x868(%r14),%rax
3a1e: e9 c4 fe ff ff jmpq 38e7 <vxlan_stop+0x1c7>
3a23: e8 00 00 00 00 callq 3a28 <vxlan_stop+0x308>
3a28: 41 8b be 84 08 00 00 mov 0x884(%r14),%edi
3a2f: 49 8b 96 60 08 00 00 mov 0x860(%r14),%rdx
/* Inverse of vxlan_igmp_join when last VNI is brought down */
static int vxlan_igmp_leave(struct vxlan_dev *vxlan)
{
struct sock *sk;
union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
int ifindex = vxlan->default_dst.remote_ifindex;
3a36: e9 6f ff ff ff jmpq 39aa <vxlan_stop+0x28a>
3a3b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000003a40 <vxlan_encap_bypass.isra.47>:
3a40: e8 00 00 00 00 callq 3a45 <vxlan_encap_bypass.isra.47+0x5>
3a45: 55 push %rbp
3a46: 49 89 d0 mov %rdx,%r8
3a49: 48 89 e5 mov %rsp,%rbp
3a4c: 41 57 push %r15
3a4e: 41 56 push %r14
3a50: 41 55 push %r13
3a52: 41 54 push %r12
vxlan_flush(vxlan);
vxlan_sock_release(vxlan);
return ret;
}
3a54: 53 push %rbx
3a55: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
3a59: 48 83 ec 30 sub $0x30,%rsp
3a5d: 48 8b 5f 20 mov 0x20(%rdi),%rbx
3a61: 4c 63 b7 80 00 00 00 movslq 0x80(%rdi),%r14
3a68: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
3a6f: 00 00
return ndst;
}
#endif
/* Bypass encapsulation if the destination is local */
static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
3a71: 48 89 44 24 28 mov %rax,0x28(%rsp)
3a76: 31 c0 xor %eax,%eax
3a78: 4c 8b a6 88 04 00 00 mov 0x488(%rsi),%r12
3a7f: 65 4c 03 25 00 00 00 add %gs:0x0(%rip),%r12 # 3a87 <vxlan_encap_bypass.isra.47+0x47>
3a86: 00
3a87: 48 8b 42 30 mov 0x30(%rdx),%rax
3a8b: 4c 8b a8 88 04 00 00 mov 0x488(%rax),%r13
{
struct pcpu_sw_netstats *tx_stats, *rx_stats;
union vxlan_addr loopback;
union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip;
struct net_device *dev = skb->dev;
int len = skb->len;
3a92: 65 4c 03 2d 00 00 00 add %gs:0x0(%rip),%r13 # 3a9a <vxlan_encap_bypass.isra.47+0x5a>
3a99: 00
return ndst;
}
#endif
/* Bypass encapsulation if the destination is local */
static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
3a9a: 0f b7 87 c4 00 00 00 movzwl 0xc4(%rdi),%eax
3aa1: 48 8b b7 d0 00 00 00 mov 0xd0(%rdi),%rsi
union vxlan_addr loopback;
union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip;
struct net_device *dev = skb->dev;
int len = skb->len;
tx_stats = this_cpu_ptr(src_vxlan->dev->tstats);
3aa8: 4c 8b 8f d8 00 00 00 mov 0xd8(%rdi),%r9
3aaf: 80 a7 90 00 00 00 f8 andb $0xf8,0x90(%rdi)
3ab6: 80 a7 92 00 00 00 fd andb $0xfd,0x92(%rdi)
rx_stats = this_cpu_ptr(dst_vxlan->dev->tstats);
3abd: 48 8b 4a 30 mov 0x30(%rdx),%rcx
3ac1: 44 89 f2 mov %r14d,%edx
3ac4: 48 01 f0 add %rsi,%rax
3ac7: 4c 29 c8 sub %r9,%rax
return skb->inner_transport_header - skb->inner_network_header;
}
static inline int skb_network_offset(const struct sk_buff *skb)
{
return skb_network_header(skb) - skb->data;
3aca: 29 c2 sub %eax,%edx
3acc: 3b 97 84 00 00 00 cmp 0x84(%rdi),%edx
3ad2: 48 89 4f 20 mov %rcx,0x20(%rdi)
3ad6: 89 97 80 00 00 00 mov %edx,0x80(%rdi)
3adc: 0f 82 be 00 00 00 jb 3ba0 <vxlan_encap_bypass.isra.47+0x160>
skb->pkt_type = PACKET_HOST;
3ae2: 89 c0 mov %eax,%eax
3ae4: 4c 01 c8 add %r9,%rax
skb->encapsulation = 0;
3ae7: 48 89 87 d8 00 00 00 mov %rax,0xd8(%rdi)
skb->dev = dst_vxlan->dev;
3aee: 66 41 83 78 40 02 cmpw $0x2,0x40(%r8)
3af4: 0f 84 90 00 00 00 je 3b8a <vxlan_encap_bypass.isra.47+0x14a>
}
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
3afa: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 3b01 <vxlan_encap_bypass.isra.47+0xc1>
BUG_ON(skb->len < skb->data_len);
3b01: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 3b08 <vxlan_encap_bypass.isra.47+0xc8>
}
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
3b08: 48 89 44 24 08 mov %rax,0x8(%rsp)
BUG_ON(skb->len < skb->data_len);
3b0d: b8 0a 00 00 00 mov $0xa,%eax
return skb->data += len;
3b12: 48 89 54 24 10 mov %rdx,0x10(%rsp)
3b17: 66 89 04 24 mov %ax,(%rsp)
3b1b: 41 f6 80 98 00 00 00 testb $0x1,0x98(%r8)
3b22: 01
__skb_pull(skb, skb_network_offset(skb));
if (remote_ip->sa.sa_family == AF_INET) {
3b23: 49 89 ff mov %rdi,%r15
3b26: 75 49 jne 3b71 <vxlan_encap_bypass.isra.47+0x131>
3b28: 49 83 44 24 10 01 addq $0x1,0x10(%r12)
loopback.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
loopback.sa.sa_family = AF_INET;
#if IS_ENABLED(CONFIG_IPV6)
} else {
loopback.sin6.sin6_addr = in6addr_loopback;
3b2e: 4d 01 74 24 18 add %r14,0x18(%r12)
3b33: 4c 89 ff mov %r15,%rdi
3b36: e8 00 00 00 00 callq 3b3b <vxlan_encap_bypass.isra.47+0xfb>
3b3b: 85 c0 test %eax,%eax
loopback.sa.sa_family = AF_INET6;
3b3d: 74 27 je 3b66 <vxlan_encap_bypass.isra.47+0x126>
3b3f: 48 83 83 60 01 00 00 addq $0x1,0x160(%rbx)
3b46: 01
3b47: 48 8b 44 24 28 mov 0x28(%rsp),%rax
#endif
}
if (dst_vxlan->flags & VXLAN_F_LEARN)
3b4c: 65 48 33 04 25 28 00 xor %gs:0x28,%rax
3b53: 00 00
3b55: 75 4b jne 3ba2 <vxlan_encap_bypass.isra.47+0x162>
3b57: 48 8d 65 d8 lea -0x28(%rbp),%rsp
vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source);
u64_stats_update_begin(&tx_stats->syncp);
tx_stats->tx_packets++;
3b5b: 5b pop %rbx
3b5c: 41 5c pop %r12
tx_stats->tx_bytes += len;
3b5e: 41 5d pop %r13
3b60: 41 5e pop %r14
3b62: 41 5f pop %r15
u64_stats_update_end(&tx_stats->syncp);
if (netif_rx(skb) == NET_RX_SUCCESS) {
3b64: 5d pop %rbp
3b65: c3 retq
3b66: 49 83 45 00 01 addq $0x1,0x0(%r13)
3b6b: 4d 01 75 08 add %r14,0x8(%r13)
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
rx_stats->rx_bytes += len;
u64_stats_update_end(&rx_stats->syncp);
} else {
dev->stats.rx_dropped++;
3b6f: eb d6 jmp 3b47 <vxlan_encap_bypass.isra.47+0x107>
3b71: 0f b7 87 c6 00 00 00 movzwl 0xc6(%rdi),%eax
}
}
3b78: 48 89 cf mov %rcx,%rdi
3b7b: 48 8d 54 06 06 lea 0x6(%rsi,%rax,1),%rdx
3b80: 48 89 e6 mov %rsp,%rsi
3b83: e8 a8 f7 ff ff callq 3330 <vxlan_snoop>
3b88: eb 9e jmp 3b28 <vxlan_encap_bypass.isra.47+0xe8>
3b8a: ba 02 00 00 00 mov $0x2,%edx
3b8f: c7 44 24 04 7f 00 00 movl $0x100007f,0x4(%rsp)
3b96: 01
tx_stats->tx_bytes += len;
u64_stats_update_end(&tx_stats->syncp);
if (netif_rx(skb) == NET_RX_SUCCESS) {
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
3b97: 66 89 14 24 mov %dx,(%rsp)
rx_stats->rx_bytes += len;
3b9b: e9 7b ff ff ff jmpq 3b1b <vxlan_encap_bypass.isra.47+0xdb>
3ba0: 0f 0b ud2
loopback.sa.sa_family = AF_INET6;
#endif
}
if (dst_vxlan->flags & VXLAN_F_LEARN)
vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source);
3ba2: e8 00 00 00 00 callq 3ba7 <vxlan_encap_bypass.isra.47+0x167>
3ba7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
3bae: 00 00
0000000000003bb0 <vxlan_exit_net>:
3bb0: e8 00 00 00 00 callq 3bb5 <vxlan_exit_net+0x5>
3bb5: 55 push %rbp
3bb6: 48 89 e5 mov %rsp,%rbp
3bb9: 41 57 push %r15
skb->dev = dst_vxlan->dev;
__skb_pull(skb, skb_network_offset(skb));
if (remote_ip->sa.sa_family == AF_INET) {
loopback.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
loopback.sa.sa_family = AF_INET;
3bbb: 41 56 push %r14
3bbd: 41 55 push %r13
skb->encapsulation = 0;
skb->dev = dst_vxlan->dev;
__skb_pull(skb, skb_network_offset(skb));
if (remote_ip->sa.sa_family == AF_INET) {
loopback.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3bbf: 41 54 push %r12
3bc1: 49 89 fe mov %rdi,%r14
3bc4: 53 push %rbx
3bc5: 4d 8d a6 10 01 00 00 lea 0x110(%r14),%r12
loopback.sa.sa_family = AF_INET;
3bcc: 48 83 ec 20 sub $0x20,%rsp
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
BUG_ON(skb->len < skb->data_len);
3bd0: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
3bd7: 00 00
rx_stats->rx_bytes += len;
u64_stats_update_end(&rx_stats->syncp);
} else {
dev->stats.rx_dropped++;
}
}
3bd9: 48 89 45 d0 mov %rax,-0x30(%rbp)
3bdd: 31 c0 xor %eax,%eax
3bdf: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 3be5 <vxlan_exit_net+0x35>
return 0;
}
static void __net_exit vxlan_exit_net(struct net *net)
{
3be5: 48 8b 97 88 14 00 00 mov 0x1488(%rdi),%rdx
3bec: 83 e8 01 sub $0x1,%eax
3bef: 48 98 cltq
3bf1: 48 8b 44 c2 18 mov 0x18(%rdx,%rax,8),%rax
struct vxlan_dev *vxlan, *next;
struct net_device *dev, *aux;
LIST_HEAD(list);
rtnl_lock();
for_each_netdev_safe(net, dev, aux)
3bf6: 48 89 45 b8 mov %rax,-0x48(%rbp)
3bfa: 48 8d 45 c0 lea -0x40(%rbp),%rax
return 0;
}
static void __net_exit vxlan_exit_net(struct net *net)
{
3bfe: 48 89 45 c0 mov %rax,-0x40(%rbp)
3c02: 48 89 45 c8 mov %rax,-0x38(%rbp)
3c06: e8 00 00 00 00 callq 3c0b <vxlan_exit_net+0x5b>
3c0b: 49 8b 86 10 01 00 00 mov 0x110(%r14),%rax
3c12: 48 8b 30 mov (%rax),%rsi
3c15: 49 39 c4 cmp %rax,%r12
3c18: 48 8d 78 b0 lea -0x50(%rax),%rdi
3c1c: 48 8d 5e b0 lea -0x50(%rsi),%rbx
3c20: 75 05 jne 3c27 <vxlan_exit_net+0x77>
3c22: eb 28 jmp 3c4c <vxlan_exit_net+0x9c>
3c24: 48 89 c3 mov %rax,%rbx
3c27: 48 81 bf 98 07 00 00 cmpq $0x0,0x798(%rdi)
3c2e: 00 00 00 00
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
struct vxlan_dev *vxlan, *next;
struct net_device *dev, *aux;
LIST_HEAD(list);
3c32: 0f 84 3a 01 00 00 je 3d72 <vxlan_exit_net+0x1c2>
rtnl_lock();
3c38: 48 8b 43 50 mov 0x50(%rbx),%rax
for_each_netdev_safe(net, dev, aux)
3c3c: 48 8d 53 50 lea 0x50(%rbx),%rdx
3c40: 48 89 df mov %rbx,%rdi
3c43: 48 83 e8 50 sub $0x50,%rax
3c47: 49 39 d4 cmp %rdx,%r12
3c4a: 75 d8 jne 3c24 <vxlan_exit_net+0x74>
3c4c: 48 8b 75 b8 mov -0x48(%rbp),%rsi
3c50: 48 8b 06 mov (%rsi),%rax
3c53: 48 8b 18 mov (%rax),%rbx
3c56: 48 39 c6 cmp %rax,%rsi
if (dev->rtnl_link_ops == &vxlan_link_ops)
3c59: 4c 8d 60 f0 lea -0x10(%rax),%r12
3c5d: 4c 8d 6b f0 lea -0x10(%rbx),%r13
3c61: 0f 84 df 00 00 00 je 3d46 <vxlan_exit_net+0x196>
3c67: 49 8b 7c 24 30 mov 0x30(%r12),%rdi
struct vxlan_dev *vxlan, *next;
struct net_device *dev, *aux;
LIST_HEAD(list);
rtnl_lock();
for_each_netdev_safe(net, dev, aux)
3c6c: 4c 3b b7 80 04 00 00 cmp 0x480(%rdi),%r14
3c73: 0f 84 b0 00 00 00 je 3d29 <vxlan_exit_net+0x179>
3c79: 49 83 bc 24 f0 00 00 cmpq $0x0,0xf0(%r12)
3c80: 00 00
if (dev->rtnl_link_ops == &vxlan_link_ops)
unregister_netdevice_queue(dev, &list);
list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
3c82: bb ff ff ff ff mov $0xffffffff,%ebx
3c87: 0f 84 93 00 00 00 je 3d20 <vxlan_exit_net+0x170>
3c8d: 8d 53 01 lea 0x1(%rbx),%edx
3c90: be 00 01 00 00 mov $0x100,%esi
3c95: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
/* If vxlan->dev is in the same netns, it has already been added
* to the list by the previous loop.
*/
if (!net_eq(dev_net(vxlan->dev), net)) {
3c9c: 48 63 d2 movslq %edx,%rdx
3c9f: e8 00 00 00 00 callq 3ca4 <vxlan_exit_net+0xf4>
3ca4: 3b 05 00 00 00 00 cmp 0x0(%rip),%eax # 3caa <vxlan_exit_net+0xfa>
static inline void gro_cells_destroy(struct gro_cells *gcells)
{
int i;
if (!gcells->cells)
3caa: 89 c3 mov %eax,%ebx
3cac: 7d 54 jge 3d02 <vxlan_exit_net+0x152>
3cae: 48 98 cltq
3cb0: 49 8b 94 24 f0 00 00 mov 0xf0(%r12),%rdx
3cb7: 00
3cb8: 48 03 14 c5 00 00 00 add 0x0(,%rax,8),%rdx
3cbf: 00
3cc0: 48 8d 7a 18 lea 0x18(%rdx),%rdi
3cc4: 49 89 d7 mov %rdx,%r15
3cc7: e8 00 00 00 00 callq 3ccc <vxlan_exit_net+0x11c>
3ccc: 49 8b 3f mov (%r15),%rdi
3ccf: 49 39 ff cmp %rdi,%r15
3cd2: 74 b9 je 3c8d <vxlan_exit_net+0xdd>
return;
for_each_possible_cpu(i) {
3cd4: 48 85 ff test %rdi,%rdi
3cd7: 74 b4 je 3c8d <vxlan_exit_net+0xdd>
3cd9: 41 83 6f 10 01 subl $0x1,0x10(%r15)
struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
3cde: 48 8b 0f mov (%rdi),%rcx
3ce1: 48 8b 57 08 mov 0x8(%rdi),%rdx
3ce5: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
3cec: 48 c7 47 08 00 00 00 movq $0x0,0x8(%rdi)
3cf3: 00
3cf4: 48 89 51 08 mov %rdx,0x8(%rcx)
netif_napi_del(&cell->napi);
3cf8: 48 89 0a mov %rcx,(%rdx)
3cfb: e8 00 00 00 00 callq 3d00 <vxlan_exit_net+0x150>
*/
static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
{
struct sk_buff *skb = list_->next;
if (skb == (struct sk_buff *)list_)
3d00: eb ca jmp 3ccc <vxlan_exit_net+0x11c>
3d02: 49 8b bc 24 f0 00 00 mov 0xf0(%r12),%rdi
3d09: 00
void skb_unlink(struct sk_buff *skb, struct sk_buff_head *list);
static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
{
struct sk_buff *next, *prev;
list->qlen--;
3d0a: e8 00 00 00 00 callq 3d0f <vxlan_exit_net+0x15f>
next = skb->next;
3d0f: 49 8b 7c 24 30 mov 0x30(%r12),%rdi
prev = skb->prev;
3d14: 49 c7 84 24 f0 00 00 movq $0x0,0xf0(%r12)
3d1b: 00 00 00 00 00
skb->next = skb->prev = NULL;
3d20: 48 8d 75 c0 lea -0x40(%rbp),%rsi
next->prev = prev;
3d24: e8 00 00 00 00 callq 3d29 <vxlan_exit_net+0x179>
prev->next = next;
3d29: 49 8b 45 10 mov 0x10(%r13),%rax
void skb_queue_purge(struct sk_buff_head *list);
static inline void __skb_queue_purge(struct sk_buff_head *list)
{
struct sk_buff *skb;
while ((skb = __skb_dequeue(list)) != NULL)
kfree_skb(skb);
3d2d: 49 8d 55 10 lea 0x10(%r13),%rdx
3d31: 4d 89 ec mov %r13,%r12
__skb_queue_purge(&cell->napi_skbs);
}
free_percpu(gcells->cells);
3d34: 48 83 e8 10 sub $0x10,%rax
3d38: 48 39 55 b8 cmp %rdx,-0x48(%rbp)
3d3c: 74 08 je 3d46 <vxlan_exit_net+0x196>
3d3e: 49 89 c5 mov %rax,%r13
3d41: e9 21 ff ff ff jmpq 3c67 <vxlan_exit_net+0xb7>
gcells->cells = NULL;
3d46: 48 8d 7d c0 lea -0x40(%rbp),%rdi
3d4a: e8 00 00 00 00 callq 3d4f <vxlan_exit_net+0x19f>
3d4f: e8 00 00 00 00 callq 3d54 <vxlan_exit_net+0x1a4>
gro_cells_destroy(&vxlan->gro_cells);
unregister_netdevice_queue(vxlan->dev, &list);
3d54: 48 8b 45 d0 mov -0x30(%rbp),%rax
3d58: 65 48 33 04 25 28 00 xor %gs:0x28,%rax
3d5f: 00 00
rtnl_lock();
for_each_netdev_safe(net, dev, aux)
if (dev->rtnl_link_ops == &vxlan_link_ops)
unregister_netdevice_queue(dev, &list);
list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
3d61: 75 1d jne 3d80 <vxlan_exit_net+0x1d0>
3d63: 48 83 c4 20 add $0x20,%rsp
3d67: 5b pop %rbx
3d68: 41 5c pop %r12
3d6a: 41 5d pop %r13
3d6c: 41 5e pop %r14
3d6e: 41 5f pop %r15
3d70: 5d pop %rbp
3d71: c3 retq
3d72: 48 8d 75 c0 lea -0x40(%rbp),%rsi
gro_cells_destroy(&vxlan->gro_cells);
unregister_netdevice_queue(vxlan->dev, &list);
}
}
unregister_netdevice_many(&list);
3d76: e8 00 00 00 00 callq 3d7b <vxlan_exit_net+0x1cb>
3d7b: e9 b8 fe ff ff jmpq 3c38 <vxlan_exit_net+0x88>
rtnl_unlock();
3d80: e8 00 00 00 00 callq 3d85 <vxlan_exit_net+0x1d5>
}
3d85: 90 nop
3d86: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
3d8d: 00 00 00
0000000000003d90 <vxlan_build_skb>:
3d90: e8 00 00 00 00 callq 3d95 <vxlan_build_skb+0x5>
3d95: 55 push %rbp
3d96: 48 89 e5 mov %rsp,%rbp
3d99: 41 57 push %r15
3d9b: 41 56 push %r14
3d9d: 41 55 push %r13
3d9f: 41 54 push %r12
3da1: 45 89 ce mov %r9d,%r14d
LIST_HEAD(list);
rtnl_lock();
for_each_netdev_safe(net, dev, aux)
if (dev->rtnl_link_ops == &vxlan_link_ops)
unregister_netdevice_queue(dev, &list);
3da4: 53 push %rbx
3da5: 48 89 fb mov %rdi,%rbx
3da8: 41 89 cc mov %ecx,%r12d
3dab: 48 83 ec 18 sub $0x18,%rsp
3daf: 80 7d 10 01 cmpb $0x1,0x10(%rbp)
}
}
unregister_netdevice_many(&list);
rtnl_unlock();
}
3db3: 4c 89 45 d0 mov %r8,-0x30(%rbp)
3db7: 45 19 ed sbb %r13d,%r13d
3dba: 41 81 e5 00 f8 ff ff and $0xfffff800,%r13d
static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
int iphdr_len, __be32 vni,
struct vxlan_metadata *md, u32 vxflags,
bool udp_sum)
{
3dc1: 41 81 c5 00 10 00 00 add $0x1000,%r13d
3dc8: 41 81 e1 00 02 00 00 and $0x200,%r9d
3dcf: 0f 85 d6 00 00 00 jne 3eab <vxlan_build_skb+0x11b>
3dd5: 48 8b 8f d0 00 00 00 mov 0xd0(%rdi),%rcx
3ddc: 48 8b bf d8 00 00 00 mov 0xd8(%rdi),%rdi
3de3: 41 89 f9 mov %edi,%r9d
3de6: 41 29 c9 sub %ecx,%r9d
struct vxlanhdr *vxh;
int min_headroom;
int err;
int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
3de9: 4c 8b 56 18 mov 0x18(%rsi),%r10
3ded: 44 0f b7 bb aa 00 00 movzwl 0xaa(%rbx),%r15d
3df4: 00
3df5: 0f b7 76 68 movzwl 0x68(%rsi),%esi
__be16 inner_protocol = htons(ETH_P_TEB);
if ((vxflags & VXLAN_F_REMCSUM_TX) &&
3df9: 45 0f b7 9a 4e 02 00 movzwl 0x24e(%r10),%r11d
3e00: 00
3e01: 41 0f b7 82 50 02 00 movzwl 0x250(%r10),%eax
3e08: 00
3e09: 45 89 fa mov %r15d,%r10d
3e0c: 66 41 81 e2 00 10 and $0x1000,%r10w
3e12: 44 01 d8 add %r11d,%eax
3e15: 83 e0 f0 and $0xfffffff0,%eax
3e18: 66 41 83 fa 01 cmp $0x1,%r10w
type |= SKB_GSO_TUNNEL_REMCSUM;
}
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
+ VXLAN_HLEN + iphdr_len
+ (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
3e1d: 8d 74 30 10 lea 0x10(%rax,%rsi,1),%esi
3e21: 19 c0 sbb %eax,%eax
3e23: f7 d0 not %eax
(skb->csum_offset == offsetof(struct udphdr, check) ||
skb->csum_offset == offsetof(struct tcphdr, check)))
type |= SKB_GSO_TUNNEL_REMCSUM;
}
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
3e25: 8d 54 16 10 lea 0x10(%rsi,%rdx,1),%edx
3e29: 83 e0 04 and $0x4,%eax
3e2c: 01 d0 add %edx,%eax
3e2e: f6 83 8e 00 00 00 01 testb $0x1,0x8e(%rbx)
3e35: 0f 84 3e 02 00 00 je 4079 <vxlan_build_skb+0x2e9>
3e3b: 8b 93 cc 00 00 00 mov 0xcc(%rbx),%edx
3e41: 48 01 d1 add %rdx,%rcx
3e44: 8b 51 20 mov 0x20(%rcx),%edx
3e47: 0f b7 ca movzwl %dx,%ecx
3e4a: c1 fa 10 sar $0x10,%edx
3e4d: 29 d1 sub %edx,%ecx
3e4f: 83 f9 01 cmp $0x1,%ecx
3e52: 0f 95 c2 setne %dl
3e55: 31 f6 xor %esi,%esi
3e57: 41 39 c1 cmp %eax,%r9d
3e5a: 0f b6 d2 movzbl %dl,%edx
3e5d: 73 05 jae 3e64 <vxlan_build_skb+0xd4>
*/
static inline int skb_header_cloned(const struct sk_buff *skb)
{
int dataref;
if (!skb->cloned)
3e5f: 44 29 c8 sub %r9d,%eax
3e62: 89 c6 mov %eax,%esi
3e64: 09 f2 or %esi,%edx
3e66: 0f 85 7d 01 00 00 jne 3fe9 <vxlan_build_skb+0x259>
};
#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
return skb->head + skb->end;
3e6c: 66 45 85 d2 test %r10w,%r10w
3e70: 0f 85 ae 01 00 00 jne 4024 <vxlan_build_skb+0x294>
3e76: 48 85 db test %rbx,%rbx
if (!skb->cloned)
return 0;
dataref = atomic_read(&skb_shinfo(skb)->dataref);
dataref = (dataref & SKB_DATAREF_MASK) - (dataref >> SKB_DATAREF_SHIFT);
return dataref != 1;
3e79: 0f 84 69 03 00 00 je 41e8 <vxlan_build_skb+0x458>
3e7f: 44 89 ee mov %r13d,%esi
3e82: 48 89 df mov %rbx,%rdi
}
static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom,
int cloned)
{
int delta = 0;
3e85: e8 00 00 00 00 callq 3e8a <vxlan_build_skb+0xfa>
if (!skb->cloned)
return 0;
dataref = atomic_read(&skb_shinfo(skb)->dataref);
dataref = (dataref & SKB_DATAREF_MASK) - (dataref >> SKB_DATAREF_SHIFT);
return dataref != 1;
3e8a: 85 c0 test %eax,%eax
3e8c: 41 89 c7 mov %eax,%r15d
int cloned)
{
int delta = 0;
if (headroom > skb_headroom(skb))
delta = headroom - skb_headroom(skb);
3e8f: 74 45 je 3ed6 <vxlan_build_skb+0x146>
3e91: 48 89 df mov %rbx,%rdi
if (delta || cloned)
3e94: e8 00 00 00 00 callq 3e99 <vxlan_build_skb+0x109>
3e99: 48 83 c4 18 add $0x18,%rsp
* Following the skb_unshare() example, in case of error, the calling function
* doesn't have to worry about freeing the original skb.
*/
static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb)
{
if (skb_vlan_tag_present(skb))
3e9d: 44 89 f8 mov %r15d,%eax
3ea0: 5b pop %rbx
3ea1: 41 5c pop %r12
3ea3: 41 5d pop %r13
3ea5: 41 5e pop %r14
err = skb_cow_head(skb, min_headroom);
if (unlikely(err))
goto out_free;
skb = vlan_hwaccel_push_inside(skb);
if (WARN_ON(!skb))
3ea7: 41 5f pop %r15
3ea9: 5d pop %rbp
3eaa: c3 retq
3eab: 0f b6 87 91 00 00 00 movzbl 0x91(%rdi),%eax
return -ENOMEM;
err = iptunnel_handle_offloads(skb, type);
3eb2: 48 8b 8f d0 00 00 00 mov 0xd0(%rdi),%rcx
3eb9: 48 8b bf d8 00 00 00 mov 0xd8(%rdi),%rdi
if (err)
3ec0: 83 e0 06 and $0x6,%eax
skb_set_inner_protocol(skb, inner_protocol);
return 0;
out_free:
kfree_skb(skb);
3ec3: 3c 06 cmp $0x6,%al
3ec5: 0f 84 83 02 00 00 je 414e <vxlan_build_skb+0x3be>
return err;
}
3ecb: 41 89 f9 mov %edi,%r9d
skb_set_inner_protocol(skb, inner_protocol);
return 0;
out_free:
kfree_skb(skb);
return err;
3ece: 41 29 c9 sub %ecx,%r9d
}
3ed1: e9 13 ff ff ff jmpq 3de9 <vxlan_build_skb+0x59>
3ed6: 48 8b 83 d8 00 00 00 mov 0xd8(%rbx),%rax
int min_headroom;
int err;
int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
__be16 inner_protocol = htons(ETH_P_TEB);
if ((vxflags & VXLAN_F_REMCSUM_TX) &&
3edd: 83 83 80 00 00 00 08 addl $0x8,0x80(%rbx)
3ee4: 41 c1 ec 08 shr $0x8,%r12d
3ee8: 41 81 e5 00 40 00 00 and $0x4000,%r13d
*
* Return the number of bytes of free space at the head of an &sk_buff.
*/
static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
return skb->data - skb->head;
3eef: 48 8d 50 f8 lea -0x8(%rax),%rdx
3ef3: 48 89 93 d8 00 00 00 mov %rdx,0xd8(%rbx)
3efa: c7 40 f8 08 00 00 00 movl $0x8,-0x8(%rax)
3f01: 44 89 60 fc mov %r12d,-0x4(%rax)
3f05: 74 57 je 3f5e <vxlan_build_skb+0x1ce>
}
unsigned char *skb_push(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len)
{
skb->data -= len;
3f07: 0f b7 8b 98 00 00 00 movzwl 0x98(%rbx),%ecx
skb->len += len;
3f0e: 48 8b 93 d8 00 00 00 mov 0xd8(%rbx),%rdx
static inline __be32 vxlan_vni_field(__be32 vni)
{
#if defined(__BIG_ENDIAN)
return (__force __be32)((__force u32)vni << 8);
#else
return (__force __be32)((__force u32)vni >> 8);
3f15: 48 2b 93 d0 00 00 00 sub 0xd0(%rbx),%rdx
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxh->vx_flags = VXLAN_HF_VNI;
vxh->vx_vni = vxlan_vni_field(vni);
if (type & SKB_GSO_TUNNEL_REMCSUM) {
3f1c: 83 e9 08 sub $0x8,%ecx
}
unsigned char *skb_push(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len)
{
skb->data -= len;
3f1f: 29 d1 sub %edx,%ecx
3f21: d1 e9 shr %ecx
3f23: 0f c9 bswap %ecx
3f25: 89 ca mov %ecx,%edx
3f27: 81 c9 00 00 00 80 or $0x80000000,%ecx
err = iptunnel_handle_offloads(skb, type);
if (err)
goto out_free;
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxh->vx_flags = VXLAN_HF_VNI;
3f2d: 66 83 bb 9a 00 00 00 cmpw $0x6,0x9a(%rbx)
3f34: 06
vxh->vx_vni = vxlan_vni_field(vni);
if (type & SKB_GSO_TUNNEL_REMCSUM) {
3f35: c7 40 f8 08 20 00 00 movl $0x2008,-0x8(%rax)
offsetof(struct tcphdr, check);
}
static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
{
__be32 vni_field = cpu_to_be32(start >> VXLAN_RCO_SHIFT);
3f3c: 0f 44 d1 cmove %ecx,%edx
3f3f: 44 09 e2 or %r12d,%edx
3f42: 89 50 fc mov %edx,-0x4(%rax)
3f45: 8b 93 cc 00 00 00 mov 0xcc(%rbx),%edx
3f4b: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
3f52: 66 83 7c 11 02 00 cmpw $0x0,0x2(%rcx,%rdx,1)
if (offset == offsetof(struct udphdr, check))
vni_field |= VXLAN_RCO_UDP;
3f58: 0f 84 39 02 00 00 je 4197 <vxlan_build_skb+0x407>
3f5e: 41 f7 c6 00 08 00 00 test $0x800,%r14d
unsigned int start;
start = skb_checksum_start_offset(skb) - sizeof(struct vxlanhdr);
vxh->vx_vni |= vxlan_compute_rco(start, skb->csum_offset);
vxh->vx_flags |= VXLAN_HF_RCO;
3f65: 74 3b je 3fa2 <vxlan_build_skb+0x212>
3f67: 48 8b 7d d0 mov -0x30(%rbp),%rdi
3f6b: 8b 17 mov (%rdi),%edx
3f6d: 85 d2 test %edx,%edx
if (type & SKB_GSO_TUNNEL_REMCSUM) {
unsigned int start;
start = skb_checksum_start_offset(skb) - sizeof(struct vxlanhdr);
vxh->vx_vni |= vxlan_compute_rco(start, skb->csum_offset);
3f6f: 74 31 je 3fa2 <vxlan_build_skb+0x212>
3f71: 81 48 f8 80 00 00 00 orl $0x80,-0x8(%rax)
return csum_fold(csum_partial(csum_start, plen, partial));
}
static inline bool skb_is_gso(const struct sk_buff *skb)
{
return skb_shinfo(skb)->gso_size;
3f78: 8b 17 mov (%rdi),%edx
3f7a: f7 c2 00 00 40 00 test $0x400000,%edx
3f80: 74 06 je 3f88 <vxlan_build_skb+0x1f8>
vxh->vx_flags |= VXLAN_HF_RCO;
if (!skb_is_gso(skb)) {
3f82: 80 48 f9 40 orb $0x40,-0x7(%rax)
3f86: 8b 17 mov (%rdi),%edx
3f88: f7 c2 00 00 08 00 test $0x80000,%edx
skb->ip_summed = CHECKSUM_NONE;
skb->encapsulation = 0;
}
}
if (vxflags & VXLAN_F_GBP)
3f8e: 74 0a je 3f9a <vxlan_build_skb+0x20a>
3f90: 48 8b 7d d0 mov -0x30(%rbp),%rdi
3f94: 80 48 f9 08 orb $0x8,-0x7(%rax)
static void vxlan_build_gbp_hdr(struct vxlanhdr *vxh, u32 vxflags,
struct vxlan_metadata *md)
{
struct vxlanhdr_gbp *gbp;
if (!md->gbp)
3f98: 8b 17 mov (%rdi),%edx
3f9a: 66 c1 c2 08 rol $0x8,%dx
3f9e: 66 89 50 fa mov %dx,-0x6(%rax)
return;
gbp = (struct vxlanhdr_gbp *)vxh;
vxh->vx_flags |= VXLAN_HF_GBP;
3fa2: 41 81 e6 00 40 00 00 and $0x4000,%r14d
if (md->gbp & VXLAN_GBP_DONT_LEARN)
3fa9: 0f 84 25 02 00 00 je 41d4 <vxlan_build_skb+0x444>
3faf: 0f b7 93 c0 00 00 00 movzwl 0xc0(%rbx),%edx
gbp->dont_learn = 1;
3fb6: 80 48 f8 04 orb $0x4,-0x8(%rax)
if (md->gbp & VXLAN_GBP_POLICY_APPLIED)
3fba: 66 81 fa 65 58 cmp $0x5865,%dx
3fbf: 0f 84 e5 01 00 00 je 41aa <vxlan_build_skb+0x41a>
gbp->policy_applied = 1;
3fc5: 66 81 fa 86 dd cmp $0xdd86,%dx
gbp->policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
3fca: 0f 84 3d 02 00 00 je 420d <vxlan_build_skb+0x47d>
3fd0: 66 83 fa 08 cmp $0x8,%dx
}
}
if (vxflags & VXLAN_F_GBP)
vxlan_build_gbp_hdr(vxh, vxflags, md);
if (vxflags & VXLAN_F_GPE) {
3fd4: 41 bf a0 ff ff ff mov $0xffffffa0,%r15d
3fda: 0f 85 b1 fe ff ff jne 3e91 <vxlan_build_skb+0x101>
err = vxlan_build_gpe_hdr(vxh, vxflags, skb->protocol);
3fe0: c6 40 fb 01 movb $0x1,-0x5(%rax)
3fe4: e9 c5 01 00 00 jmpq 41ae <vxlan_build_skb+0x41e>
static int vxlan_build_gpe_hdr(struct vxlanhdr *vxh, u32 vxflags,
__be16 protocol)
{
struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)vxh;
gpe->np_applied = 1;
3fe9: 83 c6 3f add $0x3f,%esi
switch (protocol) {
3fec: 31 d2 xor %edx,%edx
3fee: b9 20 00 08 02 mov $0x2080020,%ecx
3ff3: 83 e6 c0 and $0xffffffc0,%esi
3ff6: 48 89 df mov %rbx,%rdi
3ff9: e8 00 00 00 00 callq 3ffe <vxlan_build_skb+0x26e>
3ffe: 85 c0 test %eax,%eax
4000: 41 89 c7 mov %eax,%r15d
4003: 0f 85 88 fe ff ff jne 3e91 <vxlan_build_skb+0x101>
return 0;
case htons(ETH_P_TEB):
gpe->next_protocol = VXLAN_GPE_NP_ETHERNET;
return 0;
}
return -EPFNOSUPPORT;
4009: 44 0f b7 bb aa 00 00 movzwl 0xaa(%rbx),%r15d
4010: 00
gpe->np_applied = 1;
switch (protocol) {
case htons(ETH_P_IP):
gpe->next_protocol = VXLAN_GPE_NP_IPV4;
4011: 45 89 fa mov %r15d,%r10d
4014: 66 41 81 e2 00 10 and $0x1000,%r10w
if (headroom > skb_headroom(skb))
delta = headroom - skb_headroom(skb);
if (delta || cloned)
return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0,
401a: 66 45 85 d2 test %r10w,%r10w
401e: 0f 84 52 fe ff ff je 3e76 <vxlan_build_skb+0xe6>
4024: 66 41 81 e7 ff ef and $0xefff,%r15w
402a: f6 83 8e 00 00 00 01 testb $0x1,0x8e(%rbx)
4031: 44 0f b7 8b a8 00 00 movzwl 0xa8(%rbx),%r9d
4038: 00
+ VXLAN_HLEN + iphdr_len
+ (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
/* Need space for new headers (invalidates iph ptr) */
err = skb_cow_head(skb, min_headroom);
if (unlikely(err))
4039: 0f 84 d4 01 00 00 je 4213 <vxlan_build_skb+0x483>
403f: 8b 83 cc 00 00 00 mov 0xcc(%rbx),%eax
4045: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
404c: 48 01 c8 add %rcx,%rax
404f: 8b 40 20 mov 0x20(%rax),%eax
4052: 0f b7 d0 movzwl %ax,%edx
4055: c1 f8 10 sar $0x10,%eax
4058: 29 c2 sub %eax,%edx
*/
static inline int skb_header_cloned(const struct sk_buff *skb)
{
int dataref;
if (!skb->cloned)
405a: 89 d0 mov %edx,%eax
405c: 31 d2 xor %edx,%edx
405e: 83 f8 01 cmp $0x1,%eax
* Following the skb_unshare() example, in case of error, the calling function
* doesn't have to worry about freeing the original skb.
*/
static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
{
skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
4061: 48 8b 83 d8 00 00 00 mov 0xd8(%rbx),%rax
4068: 0f 95 c2 setne %dl
406b: 31 f6 xor %esi,%esi
406d: 48 29 c8 sub %rcx,%rax
};
#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
return skb->head + skb->end;
4070: 83 f8 03 cmp $0x3,%eax
4073: 89 c1 mov %eax,%ecx
4075: 77 3a ja 40b1 <vxlan_build_skb+0x321>
4077: eb 31 jmp 40aa <vxlan_build_skb+0x31a>
4079: 41 39 c1 cmp %eax,%r9d
407c: 0f 82 c0 00 00 00 jb 4142 <vxlan_build_skb+0x3b2>
if (!skb->cloned)
return 0;
dataref = atomic_read(&skb_shinfo(skb)->dataref);
dataref = (dataref & SKB_DATAREF_MASK) - (dataref >> SKB_DATAREF_SHIFT);
return dataref != 1;
4082: 66 45 85 d2 test %r10w,%r10w
4086: 0f 84 ea fd ff ff je 3e76 <vxlan_build_skb+0xe6>
408c: 44 0f b7 8b a8 00 00 movzwl 0xa8(%rbx),%r9d
4093: 00
*
* Return the number of bytes of free space at the head of an &sk_buff.
*/
static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
return skb->data - skb->head;
4094: 66 41 81 e7 ff ef and $0xefff,%r15w
if (!skb->cloned)
return 0;
dataref = atomic_read(&skb_shinfo(skb)->dataref);
dataref = (dataref & SKB_DATAREF_MASK) - (dataref >> SKB_DATAREF_SHIFT);
return dataref != 1;
409a: 48 2b bb d0 00 00 00 sub 0xd0(%rbx),%rdi
static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom,
int cloned)
{
int delta = 0;
if (headroom > skb_headroom(skb))
40a1: 83 ff 03 cmp $0x3,%edi
*
* Return the number of bytes of free space at the head of an &sk_buff.
*/
static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
return skb->data - skb->head;
40a4: 89 f9 mov %edi,%ecx
static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom,
int cloned)
{
int delta = 0;
if (headroom > skb_headroom(skb))
40a6: 77 32 ja 40da <vxlan_build_skb+0x34a>
40a8: 31 d2 xor %edx,%edx
40aa: be 04 00 00 00 mov $0x4,%esi
40af: 29 ce sub %ecx,%esi
40b1: 09 f2 or %esi,%edx
* Following the skb_unshare() example, in case of error, the calling function
* doesn't have to worry about freeing the original skb.
*/
static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb)
{
if (skb_vlan_tag_present(skb))
40b3: 74 25 je 40da <vxlan_build_skb+0x34a>
40b5: 83 c6 3f add $0x3f,%esi
40b8: 31 d2 xor %edx,%edx
40ba: b9 20 00 08 02 mov $0x2080020,%ecx
* Following the skb_unshare() example, in case of error, the calling function
* doesn't have to worry about freeing the original skb.
*/
static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
{
skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
40bf: 83 e6 c0 and $0xffffffc0,%esi
40c2: 48 89 df mov %rbx,%rdi
40c5: 44 89 4d c8 mov %r9d,-0x38(%rbp)
40c9: e8 00 00 00 00 callq 40ce <vxlan_build_skb+0x33e>
*
* Return the number of bytes of free space at the head of an &sk_buff.
*/
static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
return skb->data - skb->head;
40ce: 85 c0 test %eax,%eax
40d0: 44 8b 4d c8 mov -0x38(%rbp),%r9d
40d4: 0f 88 01 01 00 00 js 41db <vxlan_build_skb+0x44b>
int cloned)
{
int delta = 0;
if (headroom > skb_headroom(skb))
delta = headroom - skb_headroom(skb);
40da: be 04 00 00 00 mov $0x4,%esi
40df: 48 89 df mov %rbx,%rdi
if (delta || cloned)
40e2: 44 89 4d c4 mov %r9d,-0x3c(%rbp)
return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0,
40e6: e8 00 00 00 00 callq 40eb <vxlan_build_skb+0x35b>
40eb: 48 8b bb d8 00 00 00 mov 0xd8(%rbx),%rdi
40f2: ba 0c 00 00 00 mov $0xc,%edx
40f7: 48 89 45 c8 mov %rax,-0x38(%rbp)
40fb: 66 41 c1 c7 08 rol $0x8,%r15w
static inline int __vlan_insert_tag(struct sk_buff *skb,
__be16 vlan_proto, u16 vlan_tci)
{
struct vlan_ethhdr *veth;
if (skb_cow_head(skb, VLAN_HLEN) < 0)
4100: 48 8d 77 04 lea 0x4(%rdi),%rsi
4104: e8 00 00 00 00 callq 4109 <vxlan_build_skb+0x379>
4109: 48 8b 4d c8 mov -0x38(%rbp),%rcx
return -ENOMEM;
veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
410d: 44 8b 4d c4 mov -0x3c(%rbp),%r9d
4111: 66 83 ab c6 00 00 00 subw $0x4,0xc6(%rbx)
4118: 04
4119: 48 85 db test %rbx,%rbx
/* Move the mac addresses to the beginning of the new header. */
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
411c: 66 44 89 49 0c mov %r9w,0xc(%rcx)
4121: 66 44 89 79 0e mov %r15w,0xe(%rcx)
4126: 0f 84 bc 00 00 00 je 41e8 <vxlan_build_skb+0x458>
/* first, the ethernet type */
veth->h_vlan_proto = vlan_proto;
/* now, the TCI */
veth->h_vlan_TCI = htons(vlan_tci);
412c: 31 c9 xor %ecx,%ecx
412e: 66 44 89 8b c0 00 00 mov %r9w,0xc0(%rbx)
4135: 00
return -ENOMEM;
veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
/* Move the mac addresses to the beginning of the new header. */
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
4136: 66 89 8b aa 00 00 00 mov %cx,0xaa(%rbx)
skb->mac_header -= VLAN_HLEN;
/* first, the ethernet type */
veth->h_vlan_proto = vlan_proto;
413d: e9 3d fd ff ff jmpq 3e7f <vxlan_build_skb+0xef>
veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
/* Move the mac addresses to the beginning of the new header. */
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
skb->mac_header -= VLAN_HLEN;
4142: 44 29 c8 sub %r9d,%eax
4145: 31 d2 xor %edx,%edx
4147: 89 c6 mov %eax,%esi
static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb,
__be16 vlan_proto,
u16 vlan_tci)
{
skb = vlan_insert_tag(skb, vlan_proto, vlan_tci);
if (skb)
4149: e9 16 fd ff ff jmpq 3e64 <vxlan_build_skb+0xd4>
/* Move the mac addresses to the beginning of the new header. */
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
skb->mac_header -= VLAN_HLEN;
/* first, the ethernet type */
veth->h_vlan_proto = vlan_proto;
414e: 0f b7 83 98 00 00 00 movzwl 0x98(%rbx),%eax
/* now, the TCI */
veth->h_vlan_TCI = htons(vlan_tci);
4155: 49 89 fa mov %rdi,%r10
static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb,
__be16 vlan_proto,
u16 vlan_tci)
{
skb = vlan_insert_tag(skb, vlan_proto, vlan_tci);
if (skb)
4158: 49 29 ca sub %rcx,%r10
415b: 45 89 d1 mov %r10d,%r9d
skb->protocol = vlan_proto;
415e: 44 29 d0 sub %r10d,%eax
4161: 3d fe 00 00 00 cmp $0xfe,%eax
static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
{
skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
skb_vlan_tag_get(skb));
if (likely(skb))
skb->vlan_tci = 0;
4166: 0f 8f 7d fc ff ff jg 3de9 <vxlan_build_skb+0x59>
416c: a8 01 test $0x1,%al
416e: 0f 85 75 fc ff ff jne 3de9 <vxlan_build_skb+0x59>
int cloned)
{
int delta = 0;
if (headroom > skb_headroom(skb))
delta = headroom - skb_headroom(skb);
4174: 0f b7 83 9a 00 00 00 movzwl 0x9a(%rbx),%eax
417b: 66 83 f8 06 cmp $0x6,%ax
}
}
static inline int skb_checksum_start_offset(const struct sk_buff *skb)
{
return skb->csum_start - skb_headroom(skb);
417f: 74 0a je 418b <vxlan_build_skb+0x3fb>
4181: 66 83 f8 10 cmp $0x10,%ax
*
* Return the number of bytes of free space at the head of an &sk_buff.
*/
static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
return skb->data - skb->head;
4185: 0f 85 5e fc ff ff jne 3de9 <vxlan_build_skb+0x59>
418b: 41 81 cd 00 40 00 00 or $0x4000,%r13d
if ((vxflags & VXLAN_F_REMCSUM_TX) &&
skb->ip_summed == CHECKSUM_PARTIAL) {
int csum_start = skb_checksum_start_offset(skb);
if (csum_start <= VXLAN_MAX_REMCSUM_START &&
4192: e9 52 fc ff ff jmpq 3de9 <vxlan_build_skb+0x59>
4197: 80 a3 91 00 00 00 f9 andb $0xf9,0x91(%rbx)
419e: 80 a3 92 00 00 00 fd andb $0xfd,0x92(%rbx)
!(csum_start & VXLAN_RCO_SHIFT_MASK) &&
(skb->csum_offset == offsetof(struct udphdr, check) ||
41a5: e9 b4 fd ff ff jmpq 3f5e <vxlan_build_skb+0x1ce>
41aa: c6 40 fb 03 movb $0x3,-0x5(%rax)
if ((vxflags & VXLAN_F_REMCSUM_TX) &&
skb->ip_summed == CHECKSUM_PARTIAL) {
int csum_start = skb_checksum_start_offset(skb);
if (csum_start <= VXLAN_MAX_REMCSUM_START &&
!(csum_start & VXLAN_RCO_SHIFT_MASK) &&
41ae: 0f b7 83 c0 00 00 00 movzwl 0xc0(%rbx),%eax
41b5: 66 89 83 b8 00 00 00 mov %ax,0xb8(%rbx)
(skb->csum_offset == offsetof(struct udphdr, check) ||
skb->csum_offset == offsetof(struct tcphdr, check)))
type |= SKB_GSO_TUNNEL_REMCSUM;
41bc: 80 a3 93 00 00 00 f7 andb $0xf7,0x93(%rbx)
41c3: 48 83 c4 18 add $0x18,%rsp
start = skb_checksum_start_offset(skb) - sizeof(struct vxlanhdr);
vxh->vx_vni |= vxlan_compute_rco(start, skb->csum_offset);
vxh->vx_flags |= VXLAN_HF_RCO;
if (!skb_is_gso(skb)) {
skb->ip_summed = CHECKSUM_NONE;
41c7: 5b pop %rbx
41c8: 31 c0 xor %eax,%eax
41ca: 41 5c pop %r12
41cc: 41 5d pop %r13
skb->encapsulation = 0;
41ce: 41 5e pop %r14
41d0: 41 5f pop %r15
41d2: 5d pop %rbp
41d3: c3 retq
41d4: b8 65 58 00 00 mov $0x5865,%eax
41d9: eb da jmp 41b5 <vxlan_build_skb+0x425>
return 0;
case htons(ETH_P_IPV6):
gpe->next_protocol = VXLAN_GPE_NP_IPV6;
return 0;
case htons(ETH_P_TEB):
gpe->next_protocol = VXLAN_GPE_NP_ETHERNET;
41db: be 01 00 00 00 mov $0x1,%esi
vxlan_build_gbp_hdr(vxh, vxflags, md);
if (vxflags & VXLAN_F_GPE) {
err = vxlan_build_gpe_hdr(vxh, vxflags, skb->protocol);
if (err < 0)
goto out_free;
inner_protocol = skb->protocol;
41e0: 48 89 df mov %rbx,%rdi
41e3: e8 00 00 00 00 callq 41e8 <vxlan_build_skb+0x458>
#define ENCAP_TYPE_IPPROTO 1
static inline void skb_set_inner_protocol(struct sk_buff *skb,
__be16 protocol)
{
skb->inner_protocol = protocol;
41e8: be d5 06 00 00 mov $0x6d5,%esi
skb->inner_protocol_type = ENCAP_TYPE_ETHER;
41ed: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
return 0;
out_free:
kfree_skb(skb);
return err;
}
41f4: e8 00 00 00 00 callq 41f9 <vxlan_build_skb+0x469>
goto out_free;
inner_protocol = skb->protocol;
}
skb_set_inner_protocol(skb, inner_protocol);
return 0;
41f9: 48 83 c4 18 add $0x18,%rsp
out_free:
kfree_skb(skb);
return err;
}
41fd: b8 f4 ff ff ff mov $0xfffffff4,%eax
4202: 5b pop %rbx
4203: 41 5c pop %r12
{
struct vxlanhdr *vxh;
int min_headroom;
int err;
int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
__be16 inner_protocol = htons(ETH_P_TEB);
4205: 41 5d pop %r13
4207: 41 5e pop %r14
4209: 41 5f pop %r15
__dev_kfree_skb_irq(skb, SKB_REASON_CONSUMED);
}
static inline void dev_kfree_skb_any(struct sk_buff *skb)
{
__dev_kfree_skb_any(skb, SKB_REASON_DROPPED);
420b: 5d pop %rbp
420c: c3 retq
420d: c6 40 fb 02 movb $0x2,-0x5(%rax)
4211: eb 9b jmp 41ae <vxlan_build_skb+0x41e>
4213: 48 8b bb d8 00 00 00 mov 0xd8(%rbx),%rdi
err = skb_cow_head(skb, min_headroom);
if (unlikely(err))
goto out_free;
skb = vlan_hwaccel_push_inside(skb);
if (WARN_ON(!skb))
421a: e9 7b fe ff ff jmpq 409a <vxlan_build_skb+0x30a>
421f: 90 nop
0000000000004220 <vxlan_xmit_one>:
4220: e8 00 00 00 00 callq 4225 <vxlan_xmit_one+0x5>
4225: 55 push %rbp
4226: 49 89 d3 mov %rdx,%r11
return 0;
out_free:
kfree_skb(skb);
return err;
}
4229: 4c 8d 96 40 08 00 00 lea 0x840(%rsi),%r10
if (unlikely(err))
goto out_free;
skb = vlan_hwaccel_push_inside(skb);
if (WARN_ON(!skb))
return -ENOMEM;
4230: 48 89 e5 mov %rsp,%rbp
return 0;
out_free:
kfree_skb(skb);
return err;
}
4233: 41 57 push %r15
4235: 41 56 push %r14
4237: 41 55 push %r13
4239: 41 54 push %r12
423b: 49 89 fd mov %rdi,%r13
switch (protocol) {
case htons(ETH_P_IP):
gpe->next_protocol = VXLAN_GPE_NP_IPV4;
return 0;
case htons(ETH_P_IPV6):
gpe->next_protocol = VXLAN_GPE_NP_IPV6;
423e: 53 push %rbx
423f: 48 89 f3 mov %rsi,%rbx
4242: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
4246: 48 81 ec f0 00 00 00 sub $0xf0,%rsp
424d: 4c 8b 67 58 mov 0x58(%rdi),%r12
}
}
static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct vxlan_rdst *rdst, bool did_rsc)
{
4251: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
4258: 00 00
*
* Get network device private data
*/
static inline void *netdev_priv(const struct net_device *dev)
{
return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
425a: 48 89 84 24 e8 00 00 mov %rax,0xe8(%rsp)
4261: 00
4262: 31 c0 xor %eax,%eax
4264: 8b 86 d8 08 00 00 mov 0x8d8(%rsi),%eax
426a: 49 83 e4 fe and $0xfffffffffffffffe,%r12
426e: 89 44 24 64 mov %eax,0x64(%rsp)
4272: 48 8b 86 70 08 00 00 mov 0x870(%rsi),%rax
4279: 48 8b 80 80 04 00 00 mov 0x480(%rax),%rax
static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
{
struct metadata_dst *md_dst = (struct metadata_dst *) skb_dst(skb);
if (md_dst && md_dst->dst.flags & DST_METADATA)
4280: 48 89 44 24 70 mov %rax,0x70(%rsp)
4285: 48 8b 86 78 08 00 00 mov 0x878(%rsi),%rax
428c: 48 89 44 24 78 mov %rax,0x78(%rsp)
4291: 0f 84 99 08 00 00 je 4b30 <vxlan_xmit_one+0x910>
__be16 src_port = 0, dst_port;
__be32 vni, label;
__be16 df = 0;
__u8 tos, ttl;
int err;
u32 flags = vxlan->flags;
4297: 41 f6 44 24 61 02 testb $0x2,0x61(%r12)
429d: 0f 84 9b 03 00 00 je 463e <vxlan_xmit_one+0x41e>
42a3: 49 81 c4 a0 00 00 00 add $0xa0,%r12
42aa: 4d 85 db test %r11,%r11
42ad: 0f 84 a9 03 00 00 je 465c <vxlan_xmit_one+0x43c>
42b3: 41 0f b7 43 1c movzwl 0x1c(%r11),%eax
bool udp_sum = false;
bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
42b8: 66 85 c0 test %ax,%ax
42bb: 66 89 84 24 84 00 00 mov %ax,0x84(%rsp)
42c2: 00
42c3: 0f 84 51 03 00 00 je 461a <vxlan_xmit_one+0x3fa>
42c9: 41 8b 43 20 mov 0x20(%r11),%eax
42cd: 4d 8d 73 48 lea 0x48(%r11),%r14
42d1: 4d 89 df mov %r11,%r15
{
struct metadata_dst *md_dst = skb_metadata_dst(skb);
struct dst_entry *dst;
if (md_dst)
return &md_dst->u.tun_info;
42d4: 89 44 24 50 mov %eax,0x50(%rsp)
42d8: 48 8d 83 54 09 00 00 lea 0x954(%rbx),%rax
info = skb_tunnel_info(skb);
if (rdst) {
42df: 48 89 44 24 68 mov %rax,0x68(%rsp)
dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
42e4: 41 0f b7 03 movzwl (%r11),%eax
42e8: 66 83 f8 0a cmp $0xa,%ax
42ec: 0f 84 3c 03 00 00 je 462e <vxlan_xmit_one+0x40e>
42f2: 41 8b 77 04 mov 0x4(%r15),%esi
42f6: 85 f6 test %esi,%esi
42f8: 0f 94 c2 sete %dl
vni = rdst->remote_vni;
42fb: 84 d2 test %dl,%dl
dst = &rdst->remote_ip;
src = &vxlan->cfg.saddr;
dst_cache = &rdst->dst_cache;
42fd: 74 3e je 433d <vxlan_xmit_one+0x11d>
42ff: 84 c9 test %cl,%cl
info = skb_tunnel_info(skb);
if (rdst) {
dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
vni = rdst->remote_vni;
dst = &rdst->remote_ip;
4301: 0f 85 d1 04 00 00 jne 47d8 <vxlan_xmit_one+0x5b8>
info = skb_tunnel_info(skb);
if (rdst) {
dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
vni = rdst->remote_vni;
4307: 48 83 83 68 01 00 00 addq $0x1,0x168(%rbx)
430e: 01
dst = &rdst->remote_ip;
src = &vxlan->cfg.saddr;
430f: 4c 89 ef mov %r13,%rdi
4312: e8 00 00 00 00 callq 4317 <vxlan_xmit_one+0xf7>
4317: 48 8b 84 24 e8 00 00 mov 0xe8(%rsp),%rax
431e: 00
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
431f: 65 48 33 04 25 28 00 xor %gs:0x28,%rax
4326: 00 00
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
4328: 0f 85 da 09 00 00 jne 4d08 <vxlan_xmit_one+0xae8>
dst = &remote_ip;
src = &local_ip;
dst_cache = &info->dst_cache;
}
if (vxlan_addr_any(dst)) {
432e: 48 8d 65 d8 lea -0x28(%rbp),%rsp
if (did_rsc) {
4332: 5b pop %rbx
4333: 41 5c pop %r12
4335: 41 5d pop %r13
}
return;
drop:
dev->stats.tx_dropped++;
4337: 41 5e pop %r14
4339: 41 5f pop %r15
433b: 5d pop %rbp
433c: c3 retq
433d: 0f b6 bb 83 09 00 00 movzbl 0x983(%rbx),%edi
rt_tx_error:
ip_rt_put(rt);
tx_error:
dev->stats.tx_errors++;
tx_free:
dev_kfree_skb(skb);
4344: 41 0f b7 95 c4 00 00 movzwl 0xc4(%r13),%edx
434b: 00
}
434c: 49 03 95 d0 00 00 00 add 0xd0(%r13),%rdx
4353: 40 84 ff test %dil,%dil
4356: 40 88 bc 24 87 00 00 mov %dil,0x87(%rsp)
435d: 00
435e: 48 89 54 24 38 mov %rdx,0x38(%rsp)
4363: 75 22 jne 4387 <vxlan_xmit_one+0x167>
4365: 66 83 f8 0a cmp $0xa,%ax
4369: 0f 84 71 03 00 00 je 46e0 <vxlan_xmit_one+0x4c0>
goto drop;
}
old_iph = ip_hdr(skb);
ttl = vxlan->cfg.ttl;
436f: 41 8b 47 04 mov 0x4(%r15),%eax
4373: 25 f0 00 00 00 and $0xf0,%eax
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
4378: 3d e0 00 00 00 cmp $0xe0,%eax
437d: 0f 94 c0 sete %al
4380: 88 84 24 87 00 00 00 mov %al,0x87(%rsp)
4387: 0f b6 83 82 09 00 00 movzbl 0x982(%rbx),%eax
438e: 3c 01 cmp $0x1,%al
4390: 88 84 24 88 00 00 00 mov %al,0x88(%rsp)
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
}
static inline bool vxlan_addr_multicast(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
4397: 0f 84 a1 04 00 00 je 483e <vxlan_xmit_one+0x61e>
439d: 8b 83 84 09 00 00 mov 0x984(%rbx),%eax
return ipv6_addr_is_multicast(&ipa->sin6.sin6_addr);
else
return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
43a3: 0f b7 93 80 09 00 00 movzwl 0x980(%rbx),%edx
43aa: 48 8b bb 80 04 00 00 mov 0x480(%rbx),%rdi
43b1: 89 84 24 80 00 00 00 mov %eax,0x80(%rsp)
ttl = vxlan->cfg.ttl;
if (!ttl && vxlan_addr_multicast(dst))
ttl = 1;
tos = vxlan->cfg.tos;
43b8: 0f b7 83 7e 09 00 00 movzwl 0x97e(%rbx),%eax
if (tos == 1)
43bf: 89 94 24 9c 00 00 00 mov %edx,0x9c(%rsp)
ttl = vxlan->cfg.ttl;
if (!ttl && vxlan_addr_multicast(dst))
ttl = 1;
tos = vxlan->cfg.tos;
43c6: 39 c2 cmp %eax,%edx
if (tos == 1)
43c8: 89 84 24 98 00 00 00 mov %eax,0x98(%rsp)
tos = ip_tunnel_get_dsfield(old_iph, skb);
label = vxlan->cfg.label;
43cf: 0f 8e 3b 04 00 00 jle 4810 <vxlan_xmit_one+0x5f0>
src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
43d5: 41 f6 85 91 00 00 00 testb $0x30,0x91(%r13)
43dc: 30
43dd: 0f 84 0c 04 00 00 je 47ef <vxlan_xmit_one+0x5cf>
tos = vxlan->cfg.tos;
if (tos == 1)
tos = ip_tunnel_get_dsfield(old_iph, skb);
label = vxlan->cfg.label;
43e3: 41 8b 85 a4 00 00 00 mov 0xa4(%r13),%eax
src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
43ea: 85 c0 test %eax,%eax
43ec: 0f 85 c0 00 00 00 jne 44b2 <vxlan_xmit_one+0x292>
43f2: 49 8b b5 d8 00 00 00 mov 0xd8(%r13),%rsi
static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
int min, int max, bool use_eth)
{
u32 hash;
if (min >= max) {
43f9: 41 0f b7 8d c0 00 00 movzwl 0xc0(%r13),%ecx
4400: 00
4401: 0f b6 56 08 movzbl 0x8(%rsi),%edx
data, proto, nhoff, hlen, flags);
}
static inline __u32 skb_get_hash(struct sk_buff *skb)
{
if (!skb->l4_hash && !skb->sw_hash)
4405: 0f b6 46 0b movzbl 0xb(%rsi),%eax
4409: 81 e9 05 41 52 21 sub $0x21524105,%ecx
440f: 44 0f b6 46 04 movzbl 0x4(%rsi),%r8d
__skb_get_hash(skb);
return skb->hash;
4414: 8d 3c 0a lea (%rdx,%rcx,1),%edi
4417: c1 e0 18 shl $0x18,%eax
/* Use default range */
inet_get_local_port_range(net, &min, &max);
}
hash = skb_get_hash(skb);
if (unlikely(!hash)) {
441a: 45 8d 0c 08 lea (%r8,%rcx,1),%r9d
441e: 8d 14 38 lea (%rax,%rdi,1),%edx
4421: 0f b6 46 0a movzbl 0xa(%rsi),%eax
if (use_eth) {
/* Can't find a normal hash, caller has indicated an
* Ethernet packet so use that to compute a hash.
*/
hash = jhash(skb->data, 2 * ETH_ALEN,
4425: 0f b6 7e 07 movzbl 0x7(%rsi),%edi
{
u32 a, b, c;
const u8 *k = key;
/* Set up the internal state */
a = b = c = JHASH_INITVAL + length + initval;
4429: c1 e0 10 shl $0x10,%eax
442c: c1 e7 18 shl $0x18,%edi
442f: 01 d0 add %edx,%eax
4431: 0f b6 56 06 movzbl 0x6(%rsi),%edx
4435: 46 8d 04 0f lea (%rdi,%r9,1),%r8d
4439: c1 e2 10 shl $0x10,%edx
443c: 41 8d 3c 10 lea (%r8,%rdx,1),%edi
4440: 0f b6 56 05 movzbl 0x5(%rsi),%edx
4444: 44 0f b6 06 movzbl (%rsi),%r8d
4448: c1 e2 08 shl $0x8,%edx
444b: 44 01 c1 add %r8d,%ecx
444e: 01 fa add %edi,%edx
4450: 0f b6 7e 03 movzbl 0x3(%rsi),%edi
4454: c1 e7 18 shl $0x18,%edi
4457: 44 8d 04 39 lea (%rcx,%rdi,1),%r8d
445b: 0f b6 7e 02 movzbl 0x2(%rsi),%edi
445f: 0f b6 4e 01 movzbl 0x1(%rsi),%ecx
4463: 0f b6 76 09 movzbl 0x9(%rsi),%esi
4467: c1 e7 10 shl $0x10,%edi
446a: c1 e1 08 shl $0x8,%ecx
446d: c1 e6 08 shl $0x8,%esi
case 10: c += (u32)k[9]<<8;
case 9: c += k[8];
case 8: b += (u32)k[7]<<24;
case 7: b += (u32)k[6]<<16;
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
4470: 44 01 c7 add %r8d,%edi
4473: 01 f0 add %esi,%eax
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4475: 89 d6 mov %edx,%esi
4477: 01 f9 add %edi,%ecx
case 10: c += (u32)k[9]<<8;
case 9: c += k[8];
case 8: b += (u32)k[7]<<24;
case 7: b += (u32)k[6]<<16;
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
4479: 31 d0 xor %edx,%eax
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
447b: c1 c6 0e rol $0xe,%esi
case 10: c += (u32)k[9]<<8;
case 9: c += k[8];
case 8: b += (u32)k[7]<<24;
case 7: b += (u32)k[6]<<16;
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
447e: 29 f0 sub %esi,%eax
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4480: 89 c6 mov %eax,%esi
4482: 31 c1 xor %eax,%ecx
4484: c1 c6 0b rol $0xb,%esi
4487: 29 f1 sub %esi,%ecx
4489: 89 ce mov %ecx,%esi
448b: 31 ca xor %ecx,%edx
448d: c1 ce 07 ror $0x7,%esi
4490: 29 f2 sub %esi,%edx
4492: 89 d6 mov %edx,%esi
__jhash_final(a, b, c);
4494: 31 d0 xor %edx,%eax
4496: c1 c6 10 rol $0x10,%esi
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4499: 29 f0 sub %esi,%eax
449b: 89 c6 mov %eax,%esi
__jhash_final(a, b, c);
449d: 31 c1 xor %eax,%ecx
449f: c1 c6 04 rol $0x4,%esi
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
44a2: 29 f1 sub %esi,%ecx
__jhash_final(a, b, c);
44a4: 31 ca xor %ecx,%edx
44a6: c1 c1 0e rol $0xe,%ecx
44a9: 29 ca sub %ecx,%edx
44ab: 31 d0 xor %edx,%eax
44ad: c1 ca 08 ror $0x8,%edx
44b0: 29 d0 sub %edx,%eax
44b2: 8b b4 24 98 00 00 00 mov 0x98(%rsp),%esi
44b9: 8b 8c 24 9c 00 00 00 mov 0x9c(%rsp),%ecx
44c0: 89 c2 mov %eax,%edx
44c2: c1 e2 10 shl $0x10,%edx
44c5: 31 d0 xor %edx,%eax
44c7: 29 f1 sub %esi,%ecx
44c9: 48 63 c9 movslq %ecx,%rcx
44cc: 48 0f af c8 imul %rax,%rcx
44d0: 48 c1 e9 20 shr $0x20,%rcx
44d4: 01 ce add %ecx,%esi
44d6: 66 c1 c6 08 rol $0x8,%si
44da: 4d 85 e4 test %r12,%r12
44dd: 66 89 74 24 62 mov %si,0x62(%rsp)
* attacker is leaked. Only upper 16 bits are relevant in the
* computation for 16 bit port value.
*/
hash ^= hash << 16;
return htons((((u64) hash * (max - min)) >> 32) + min);
44e2: 0f 84 7a 05 00 00 je 4a62 <vxlan_xmit_one+0x842>
44e8: 41 0f b6 44 24 2b movzbl 0x2b(%r12),%eax
44ee: 48 8d 94 24 94 00 00 lea 0x94(%rsp),%rdx
44f5: 00
44f6: 88 84 24 87 00 00 00 mov %al,0x87(%rsp)
44fd: 41 0f b6 44 24 2a movzbl 0x2a(%r12),%eax
4503: 88 84 24 88 00 00 00 mov %al,0x88(%rsp)
vxlan->cfg.port_max, true);
if (info) {
450a: 41 8b 44 24 2c mov 0x2c(%r12),%eax
450f: 89 84 24 80 00 00 00 mov %eax,0x80(%rsp)
4516: 41 0f b6 44 24 29 movzbl 0x29(%r12),%eax
ttl = info->key.ttl;
451c: 83 e0 01 and $0x1,%eax
}
}
static inline void *ip_tunnel_info_opts(struct ip_tunnel_info *info)
{
return info + 1;
451f: 41 80 7c 24 48 00 cmpb $0x0,0x48(%r12)
4525: 88 44 24 48 mov %al,0x48(%rsp)
4529: 49 8d 44 24 50 lea 0x50(%r12),%rax
tos = info->key.tos;
452e: 48 0f 44 c2 cmove %rdx,%rax
4532: 48 89 44 24 40 mov %rax,0x40(%rsp)
4537: 48 8b 7c 24 70 mov 0x70(%rsp),%rdi
label = info->key.label;
453c: 48 39 7c 24 78 cmp %rdi,0x78(%rsp)
4541: 0f 95 44 24 70 setne 0x70(%rsp)
udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
4546: 66 41 83 3f 02 cmpw $0x2,(%r15)
454b: 0f 84 2e 03 00 00 je 487f <vxlan_xmit_one+0x65f>
4551: 48 8b 83 68 08 00 00 mov 0x868(%rbx),%rax
4558: 48 85 c0 test %rax,%rax
455b: 0f 84 a6 fd ff ff je 4307 <vxlan_xmit_one+0xe7>
4561: 48 8b 40 10 mov 0x10(%rax),%rax
4565: 0f b6 8c 24 88 00 00 movzbl 0x88(%rsp),%ecx
456c: 00
__be16 df = 0;
__u8 tos, ttl;
int err;
u32 flags = vxlan->flags;
bool udp_sum = false;
bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
456d: 48 8b 40 20 mov 0x20(%rax),%rax
4571: 48 89 44 24 30 mov %rax,0x30(%rsp)
md = ip_tunnel_info_opts(info);
} else {
md->gbp = skb->mark;
}
if (dst->sa.sa_family == AF_INET) {
4576: 48 8b 44 24 68 mov 0x68(%rsp),%rax
457b: 48 83 c0 08 add $0x8,%rax
457f: 4d 85 db test %r11,%r11
#if IS_ENABLED(CONFIG_IPV6)
} else {
struct dst_entry *ndst;
u32 rt6i_flags;
if (!vxlan->vn6_sock)
4582: 48 89 44 24 78 mov %rax,0x78(%rsp)
4587: 49 8d 47 08 lea 0x8(%r15),%rax
458b: 48 89 44 24 68 mov %rax,0x68(%rsp)
4590: 0f 84 93 05 00 00 je 4b29 <vxlan_xmit_one+0x909>
goto drop;
sk = vxlan->vn6_sock->sock->sk;
ndst = vxlan6_get_route(vxlan, skb,
4596: 41 8b 53 24 mov 0x24(%r11),%edx
459a: 48 8b 44 24 78 mov 0x78(%rsp),%rax
struct dst_entry *ndst;
u32 rt6i_flags;
if (!vxlan->vn6_sock)
goto drop;
sk = vxlan->vn6_sock->sock->sk;
459f: 44 8b 84 24 80 00 00 mov 0x80(%rsp),%r8d
45a6: 00
ndst = vxlan6_get_route(vxlan, skb,
45a7: 4d 8d 4f 08 lea 0x8(%r15),%r9
45ab: 4c 89 74 24 08 mov %r14,0x8(%rsp)
45b0: 4c 89 64 24 10 mov %r12,0x10(%rsp)
45b5: 4c 89 ee mov %r13,%rsi
rdst ? rdst->remote_ifindex : 0, tos,
label, &dst->sin6.sin6_addr,
45b8: 4c 89 d7 mov %r10,%rdi
45bb: 48 89 04 24 mov %rax,(%rsp)
45bf: e8 ac c4 ff ff callq a70 <vxlan6_get_route>
if (!vxlan->vn6_sock)
goto drop;
sk = vxlan->vn6_sock->sock->sk;
ndst = vxlan6_get_route(vxlan, skb,
45c4: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
45ca: 49 89 c6 mov %rax,%r14
45cd: 0f 87 2c 06 00 00 ja 4bff <vxlan_xmit_one+0x9df>
45d3: 48 3b 58 18 cmp 0x18(%rax),%rbx
45d7: 0f 84 90 05 00 00 je 4b6d <vxlan_xmit_one+0x94d>
45dd: 4d 85 e4 test %r12,%r12
45e0: 8b 80 14 01 00 00 mov 0x114(%rax),%eax
45e6: 0f 85 06 01 00 00 jne 46f2 <vxlan_xmit_one+0x4d2>
45ec: 89 c2 mov %eax,%edx
45ee: c1 ea 1f shr $0x1f,%edx
45f1: 84 d2 test %dl,%dl
45f3: 0f 84 f9 00 00 00 je 46f2 <vxlan_xmit_one+0x4d2>
rdst ? rdst->remote_ifindex : 0, tos,
label, &dst->sin6.sin6_addr,
&src->sin6.sin6_addr,
dst_cache, info);
if (IS_ERR(ndst)) {
45f9: a9 00 00 00 30 test $0x30000000,%eax
45fe: 0f 84 b0 05 00 00 je 4bb4 <vxlan_xmit_one+0x994>
&dst->sin6.sin6_addr);
dev->stats.tx_carrier_errors++;
goto tx_error;
}
if (ndst->dev == dev) {
4604: 8b 44 24 64 mov 0x64(%rsp),%eax
4608: c1 e8 07 shr $0x7,%eax
460b: 83 f0 01 xor $0x1,%eax
goto tx_error;
}
/* Bypass encapsulation if the destination is local */
rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
if (!info && rt6i_flags & RTF_LOCAL &&
460e: 83 e0 01 and $0x1,%eax
dev->stats.collisions++;
goto tx_error;
}
/* Bypass encapsulation if the destination is local */
rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
4611: 88 44 24 48 mov %al,0x48(%rsp)
4615: e9 e1 00 00 00 jmpq 46fb <vxlan_xmit_one+0x4db>
if (!info && rt6i_flags & RTF_LOCAL &&
461a: 0f b7 83 7c 09 00 00 movzwl 0x97c(%rbx),%eax
4621: 66 89 84 24 84 00 00 mov %ax,0x84(%rsp)
4628: 00
4629: e9 9b fc ff ff jmpq 42c9 <vxlan_xmit_one+0xa9>
462e: 49 8b 57 08 mov 0x8(%r15),%rdx
4632: 49 0b 57 10 or 0x10(%r15),%rdx
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
return;
}
if (!info)
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
4636: 0f 94 c2 sete %dl
4639: e9 bd fc ff ff jmpq 42fb <vxlan_xmit_one+0xdb>
463e: 4d 8b a4 24 90 00 00 mov 0x90(%r12),%r12
4645: 00
4646: 4d 85 e4 test %r12,%r12
4649: 0f 84 e1 04 00 00 je 4b30 <vxlan_xmit_one+0x910>
bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
info = skb_tunnel_info(skb);
if (rdst) {
dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
464f: 49 83 c4 1c add $0x1c,%r12
4653: 4d 85 db test %r11,%r11
4656: 0f 85 57 fc ff ff jne 42b3 <vxlan_xmit_one+0x93>
465c: 41 0f b7 44 24 32 movzwl 0x32(%r12),%eax
static inline bool ipv6_addr_any(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul = (const unsigned long *)a;
return (ul[0] | ul[1]) == 0UL;
4662: 66 85 c0 test %ax,%ax
4665: 66 89 84 24 84 00 00 mov %ax,0x84(%rsp)
466c: 00
466d: 75 0f jne 467e <vxlan_xmit_one+0x45e>
dst = skb_dst(skb);
if (dst && dst->lwtstate)
466f: 0f b7 83 7c 09 00 00 movzwl 0x97c(%rbx),%eax
4676: 66 89 84 24 84 00 00 mov %ax,0x84(%rsp)
467d: 00
467e: 49 8b 04 24 mov (%r12),%rax
info->options_len = len;
}
static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstate)
{
return (struct ip_tunnel_info *)lwtstate->data;
4682: 48 c1 e8 20 shr $0x20,%rax
bool udp_sum = false;
bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
info = skb_tunnel_info(skb);
if (rdst) {
4686: 41 f6 44 24 49 02 testb $0x2,0x49(%r12)
if (!info) {
WARN_ONCE(1, "%s: Missing encapsulation instructions\n",
dev->name);
goto drop;
}
dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
468c: 48 89 44 24 50 mov %rax,0x50(%rsp)
4691: 0f 85 80 03 00 00 jne 4a17 <vxlan_xmit_one+0x7f7>
4697: 41 8b 44 24 0c mov 0xc(%r12),%eax
469c: ba 02 00 00 00 mov $0x2,%edx
46a1: 66 89 94 24 a0 00 00 mov %dx,0xa0(%rsp)
46a8: 00
46a9: 89 84 24 a4 00 00 00 mov %eax,0xa4(%rsp)
static inline __be32 vxlan_tun_id_to_vni(__be64 tun_id)
{
#if defined(__BIG_ENDIAN)
return (__force __be32)tun_id;
#else
return (__force __be32)((__force u64)tun_id >> 32);
46b0: 41 8b 44 24 08 mov 0x8(%r12),%eax
46b5: 89 84 24 c4 00 00 00 mov %eax,0xc4(%rsp)
46bc: b8 02 00 00 00 mov $0x2,%eax
}
static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
*tun_info)
{
return tun_info->mode & IP_TUNNEL_INFO_IPV6 ? AF_INET6 : AF_INET;
46c1: 48 8d bc 24 c0 00 00 lea 0xc0(%rsp),%rdi
46c8: 00
vni = vxlan_tun_id_to_vni(info->key.tun_id);
remote_ip.sa.sa_family = ip_tunnel_info_af(info);
if (remote_ip.sa.sa_family == AF_INET) {
remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
46c9: 4d 8d 74 24 38 lea 0x38(%r12),%r14
dev->name);
goto drop;
}
dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
vni = vxlan_tun_id_to_vni(info->key.tun_id);
remote_ip.sa.sa_family = ip_tunnel_info_af(info);
46ce: 4c 8d bc 24 a0 00 00 lea 0xa0(%rsp),%r15
46d5: 00
46d6: 48 89 7c 24 68 mov %rdi,0x68(%rsp)
if (remote_ip.sa.sa_family == AF_INET) {
remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
46db: e9 08 fc ff ff jmpq 42e8 <vxlan_xmit_one+0xc8>
local_ip.sin.sin_addr.s_addr = info->key.u.ipv4.src;
46e0: 41 0f b6 47 08 movzbl 0x8(%r15),%eax
46e5: 3d ff 00 00 00 cmp $0xff,%eax
46ea: 0f 94 c0 sete %al
46ed: e9 8e fc ff ff jmpq 4380 <vxlan_xmit_one+0x160>
} else {
remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst;
local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
}
dst = &remote_ip;
src = &local_ip;
46f2: 4d 85 e4 test %r12,%r12
46f5: 0f 84 09 ff ff ff je 4604 <vxlan_xmit_one+0x3e4>
dst_cache = &info->dst_cache;
46fb: 41 0f b7 85 c0 00 00 movzwl 0xc0(%r13),%eax
4702: 00
local_ip.sin.sin_addr.s_addr = info->key.u.ipv4.src;
} else {
remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst;
local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
}
dst = &remote_ip;
4703: 66 83 f8 08 cmp $0x8,%ax
src = &local_ip;
4707: 0f 84 8e 03 00 00 je 4a9b <vxlan_xmit_one+0x87b>
470d: 44 0f b6 bc 24 88 00 movzbl 0x88(%rsp),%r15d
4714: 00 00
return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
}
static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
{
return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
4716: 45 31 e4 xor %r12d,%r12d
4719: 41 83 e7 fc and $0xfffffffc,%r15d
471d: 66 3d 86 dd cmp $0xdd86,%ax
4721: 0f 84 60 04 00 00 je 4b87 <vxlan_xmit_one+0x967>
goto tx_error;
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
return;
}
if (!info)
4727: 80 bc 24 87 00 00 00 cmpb $0x0,0x87(%rsp)
472e: 00
472f: 0f 84 52 03 00 00 je 4a87 <vxlan_xmit_one+0x867>
/* Extract dsfield from inner protocol */
static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
const struct sk_buff *skb)
{
if (skb->protocol == htons(ETH_P_IP))
4735: 0f b6 74 24 70 movzbl 0x70(%rsp),%esi
473a: 4c 89 ef mov %r13,%rdi
* ECN codepoint of the outside header to ECT(0) if the ECN codepoint of
* the inside header is CE.
*/
static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner)
{
outer &= ~INET_ECN_MASK;
473d: e8 00 00 00 00 callq 4742 <vxlan_xmit_one+0x522>
4742: 0f b6 44 24 48 movzbl 0x48(%rsp),%eax
4747: 44 8b 4c 24 64 mov 0x64(%rsp),%r9d
474c: ba 28 00 00 00 mov $0x28,%edx
return iph->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
4751: 4c 8b 44 24 40 mov 0x40(%rsp),%r8
4756: 8b 4c 24 50 mov 0x50(%rsp),%ecx
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip6_dst_hoplimit(ndst);
475a: 4c 89 f6 mov %r14,%rsi
475d: 4c 89 ef mov %r13,%rdi
4760: 89 04 24 mov %eax,(%rsp)
4763: e8 28 f6 ff ff callq 3d90 <vxlan_build_skb>
skb_scrub_packet(skb, xnet);
4768: 85 c0 test %eax,%eax
476a: 0f 88 58 03 00 00 js 4ac8 <vxlan_xmit_one+0x8a8>
4770: 0f b6 44 24 48 movzbl 0x48(%rsp),%eax
err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
4775: 0f b7 74 24 62 movzwl 0x62(%rsp),%esi
477a: 45 09 fc or %r15d,%r12d
477d: 0f b7 8c 24 84 00 00 movzwl 0x84(%rsp),%ecx
4784: 00
4785: 4c 8b 4c 24 68 mov 0x68(%rsp),%r9
478a: 45 0f b6 e4 movzbl %r12b,%r12d
478e: 4c 8b 44 24 78 mov 0x78(%rsp),%r8
4793: 44 89 24 24 mov %r12d,(%rsp)
4797: 4c 89 ea mov %r13,%rdx
vni, md, flags, udp_sum);
if (err < 0) {
479a: 4c 89 f7 mov %r14,%rdi
479d: 83 f0 01 xor $0x1,%eax
dst_release(ndst);
return;
}
udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
47a0: 89 74 24 18 mov %esi,0x18(%rsp)
47a4: 48 8b 74 24 30 mov 0x30(%rsp),%rsi
47a9: 0f b6 c0 movzbl %al,%eax
47ac: 89 4c 24 20 mov %ecx,0x20(%rsp)
47b0: 48 89 d9 mov %rbx,%rcx
47b3: 89 44 24 28 mov %eax,0x28(%rsp)
47b7: 8b 84 24 80 00 00 00 mov 0x80(%rsp),%eax
47be: 89 44 24 10 mov %eax,0x10(%rsp)
47c2: 0f b6 84 24 87 00 00 movzbl 0x87(%rsp),%eax
47c9: 00
47ca: 89 44 24 08 mov %eax,0x8(%rsp)
47ce: e8 00 00 00 00 callq 47d3 <vxlan_xmit_one+0x5b3>
47d3: e9 3f fb ff ff jmpq 4317 <vxlan_xmit_one+0xf7>
47d8: 48 8b b3 70 08 00 00 mov 0x870(%rbx),%rsi
47df: 4c 89 d2 mov %r10,%rdx
47e2: 4c 89 ef mov %r13,%rdi
47e5: e8 56 f2 ff ff callq 3a40 <vxlan_encap_bypass.isra.47>
47ea: e9 28 fb ff ff jmpq 4317 <vxlan_xmit_one+0xf7>
47ef: 4c 89 ef mov %r13,%rdi
47f2: 4c 89 5c 24 40 mov %r11,0x40(%rsp)
47f7: 4c 89 54 24 48 mov %r10,0x48(%rsp)
47fc: e8 00 00 00 00 callq 4801 <vxlan_xmit_one+0x5e1>
4801: 4c 8b 5c 24 40 mov 0x40(%rsp),%r11
4806: 4c 8b 54 24 48 mov 0x48(%rsp),%r10
}
if (vxlan_addr_any(dst)) {
if (did_rsc) {
/* short-circuited back to local bridge */
vxlan_encap_bypass(skb, vxlan, vxlan);
480b: e9 d3 fb ff ff jmpq 43e3 <vxlan_xmit_one+0x1c3>
4810: 48 8d 94 24 9c 00 00 lea 0x9c(%rsp),%rdx
4817: 00
4818: 48 8d b4 24 98 00 00 lea 0x98(%rsp),%rsi
481f: 00
}
static inline __u32 skb_get_hash(struct sk_buff *skb)
{
if (!skb->l4_hash && !skb->sw_hash)
__skb_get_hash(skb);
4820: 4c 89 5c 24 40 mov %r11,0x40(%rsp)
4825: 4c 89 54 24 48 mov %r10,0x48(%rsp)
482a: e8 00 00 00 00 callq 482f <vxlan_xmit_one+0x60f>
482f: 4c 8b 5c 24 40 mov 0x40(%rsp),%r11
4834: 4c 8b 54 24 48 mov 0x48(%rsp),%r10
4839: e9 97 fb ff ff jmpq 43d5 <vxlan_xmit_one+0x1b5>
483e: 41 0f b7 85 c0 00 00 movzwl 0xc0(%r13),%eax
4845: 00
{
u32 hash;
if (min >= max) {
/* Use default range */
inet_get_local_port_range(net, &min, &max);
4846: 66 83 f8 08 cmp $0x8,%ax
484a: 0f 84 4f 03 00 00 je 4b9f <vxlan_xmit_one+0x97f>
4850: 66 3d 86 dd cmp $0xdd86,%ax
4854: c6 84 24 88 00 00 00 movb $0x0,0x88(%rsp)
485b: 00
485c: 0f 85 3b fb ff ff jne 439d <vxlan_xmit_one+0x17d>
4862: 48 8b 44 24 38 mov 0x38(%rsp),%rax
4867: 0f b7 00 movzwl (%rax),%eax
486a: 66 c1 c0 08 rol $0x8,%ax
486e: 66 c1 e8 04 shr $0x4,%ax
4872: 66 89 84 24 88 00 00 mov %ax,0x88(%rsp)
4879: 00
/* Extract dsfield from inner protocol */
static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
const struct sk_buff *skb)
{
if (skb->protocol == htons(ETH_P_IP))
487a: e9 1e fb ff ff jmpq 439d <vxlan_xmit_one+0x17d>
487f: 48 8b 83 60 08 00 00 mov 0x860(%rbx),%rax
return iph->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
return ipv6_get_dsfield((const struct ipv6hdr *)iph);
else
return 0;
4886: 48 85 c0 test %rax,%rax
4889: 0f 84 78 fa ff ff je 4307 <vxlan_xmit_one+0xe7>
static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
const struct sk_buff *skb)
{
if (skb->protocol == htons(ETH_P_IP))
return iph->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
488f: 48 8b 40 10 mov 0x10(%rax),%rax
}
static inline __u8 ipv6_get_dsfield(const struct ipv6hdr *ipv6h)
{
return ntohs(*(const __be16 *)ipv6h) >> 4;
4893: 4d 85 db test %r11,%r11
4896: 45 8b 47 04 mov 0x4(%r15),%r8d
489a: 0f b6 8c 24 88 00 00 movzbl 0x88(%rsp),%ecx
48a1: 00
48a2: 48 8b 40 20 mov 0x20(%rax),%rax
48a6: 48 89 44 24 78 mov %rax,0x78(%rsp)
48ab: 48 8b 44 24 68 mov 0x68(%rsp),%rax
} else {
md->gbp = skb->mark;
}
if (dst->sa.sa_family == AF_INET) {
if (!vxlan->vn4_sock)
48b0: 4c 8d 48 04 lea 0x4(%rax),%r9
48b4: 0f 84 ab 03 00 00 je 4c65 <vxlan_xmit_one+0xa45>
48ba: 41 8b 53 24 mov 0x24(%r11),%edx
48be: 4c 89 d7 mov %r10,%rdi
goto drop;
sk = vxlan->vn4_sock->sock->sk;
48c1: 4c 89 64 24 08 mov %r12,0x8(%rsp)
rt = vxlan_get_route(vxlan, skb,
48c6: 4c 89 34 24 mov %r14,(%rsp)
48ca: 4c 89 ee mov %r13,%rsi
48cd: e8 2e ed ff ff callq 3600 <vxlan_get_route>
}
if (dst->sa.sa_family == AF_INET) {
if (!vxlan->vn4_sock)
goto drop;
sk = vxlan->vn4_sock->sock->sk;
48d2: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
48d8: 49 89 c2 mov %rax,%r10
rt = vxlan_get_route(vxlan, skb,
48db: 0f 87 c0 03 00 00 ja 4ca1 <vxlan_xmit_one+0xa81>
48e1: 48 8b 50 18 mov 0x18(%rax),%rdx
48e5: 48 39 d3 cmp %rdx,%rbx
48e8: 0f 84 7e 03 00 00 je 4c6c <vxlan_xmit_one+0xa4c>
48ee: 4d 85 e4 test %r12,%r12
48f1: 0f 84 87 03 00 00 je 4c7e <vxlan_xmit_one+0xa5e>
48f7: 45 0f b7 74 24 28 movzwl 0x28(%r12),%r14d
48fd: 41 83 e6 01 and $0x1,%r14d
4901: 41 f7 de neg %r14d
rdst ? rdst->remote_ifindex : 0, tos,
dst->sin.sin_addr.s_addr,
&src->sin.sin_addr.s_addr,
dst_cache, info);
if (IS_ERR(rt)) {
4904: 41 83 e6 40 and $0x40,%r14d
if (dst->sa.sa_family == AF_INET) {
if (!vxlan->vn4_sock)
goto drop;
sk = vxlan->vn4_sock->sock->sk;
rt = vxlan_get_route(vxlan, skb,
4908: 41 0f b7 85 c0 00 00 movzwl 0xc0(%r13),%eax
490f: 00
rdst ? rdst->remote_ifindex : 0, tos,
dst->sin.sin_addr.s_addr,
&src->sin.sin_addr.s_addr,
dst_cache, info);
if (IS_ERR(rt)) {
4910: 66 83 f8 08 cmp $0x8,%ax
&dst->sin.sin_addr.s_addr);
dev->stats.tx_carrier_errors++;
goto tx_error;
}
if (rt->dst.dev == dev) {
4914: 0f 84 14 03 00 00 je 4c2e <vxlan_xmit_one+0xa0e>
491a: 0f b6 bc 24 88 00 00 movzbl 0x88(%rsp),%edi
4921: 00
dev->stats.collisions++;
goto rt_tx_error;
}
/* Bypass encapsulation if the destination is local */
if (!info && rt->rt_flags & RTCF_LOCAL &&
4922: 45 31 e4 xor %r12d,%r12d
4925: 83 e7 fc and $0xfffffffc,%edi
return;
}
if (!info)
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT)
4928: 66 3d 86 dd cmp $0xdd86,%ax
492c: 40 88 bc 24 80 00 00 mov %dil,0x80(%rsp)
4933: 00
union vxlan_addr *src;
struct vxlan_metadata _md;
struct vxlan_metadata *md = &_md;
__be16 src_port = 0, dst_port;
__be32 vni, label;
__be16 df = 0;
4934: 0f 84 b3 01 00 00 je 4aed <vxlan_xmit_one+0x8cd>
493a: 80 bc 24 87 00 00 00 cmpb $0x0,0x87(%rsp)
4941: 00
/* Extract dsfield from inner protocol */
static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
const struct sk_buff *skb)
{
if (skb->protocol == htons(ETH_P_IP))
4942: 75 23 jne 4967 <vxlan_xmit_one+0x747>
4944: 49 8b 42 28 mov 0x28(%r10),%rax
4948: 48 83 e0 fc and $0xfffffffffffffffc,%rax
494c: 8b 40 24 mov 0x24(%rax),%eax
494f: 85 c0 test %eax,%eax
4951: 75 0d jne 4960 <vxlan_xmit_one+0x740>
4953: 48 8b 82 80 04 00 00 mov 0x480(%rdx),%rax
return iph->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
495a: 8b 80 a4 03 00 00 mov 0x3a4(%rax),%eax
4960: 88 84 24 87 00 00 00 mov %al,0x87(%rsp)
4967: 0f b6 44 24 48 movzbl 0x48(%rsp),%eax
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT)
df = htons(IP_DF);
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
496c: 44 8b 4c 24 64 mov 0x64(%rsp),%r9d
4971: 4c 89 d6 mov %r10,%rsi
static inline u32
dst_metric_raw(const struct dst_entry *dst, const int metric)
{
u32 *p = DST_METRICS_PTR(dst);
return p[metric-1];
4974: 4c 8b 44 24 40 mov 0x40(%rsp),%r8
4979: 8b 4c 24 50 mov 0x50(%rsp),%ecx
return skb->skb_iif;
}
static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
{
int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
497d: ba 14 00 00 00 mov $0x14,%edx
struct net *net = dev_net(dst->dev);
if (hoplimit == 0)
4982: 4c 89 ef mov %r13,%rdi
hoplimit = net->ipv4.sysctl_ip_default_ttl;
4985: 4c 89 94 24 88 00 00 mov %r10,0x88(%rsp)
498c: 00
498d: 89 04 24 mov %eax,(%rsp)
4990: e8 fb f3 ff ff callq 3d90 <vxlan_build_skb>
4995: 85 c0 test %eax,%eax
err = vxlan_build_skb(skb, &rt->dst, sizeof(struct iphdr),
4997: 4c 8b 94 24 88 00 00 mov 0x88(%rsp),%r10
499e: 00
499f: 0f 88 30 01 00 00 js 4ad5 <vxlan_xmit_one+0x8b5>
49a5: 0f b6 44 24 48 movzbl 0x48(%rsp),%eax
49aa: 48 8b 5c 24 68 mov 0x68(%rsp),%rbx
49af: 45 0f b7 f6 movzwl %r14w,%r14d
49b3: 0f b6 74 24 70 movzbl 0x70(%rsp),%esi
49b8: 45 8b 47 04 mov 0x4(%r15),%r8d
49bc: 4c 89 ea mov %r13,%rdx
49bf: 44 0f b6 8c 24 80 00 movzbl 0x80(%rsp),%r9d
49c6: 00 00
vni, md, flags, udp_sum);
if (err < 0)
49c8: 4c 89 d7 mov %r10,%rdi
49cb: 8b 4b 04 mov 0x4(%rbx),%ecx
49ce: 44 89 74 24 08 mov %r14d,0x8(%rsp)
49d3: 83 f0 01 xor $0x1,%eax
goto xmit_tx_error;
udp_tunnel_xmit_skb(rt, sk, skb, src->sin.sin_addr.s_addr,
49d6: 0f b6 c0 movzbl %al,%eax
49d9: 89 74 24 20 mov %esi,0x20(%rsp)
49dd: 0f b7 74 24 62 movzwl 0x62(%rsp),%esi
49e2: 89 44 24 28 mov %eax,0x28(%rsp)
49e6: 0f b7 84 24 84 00 00 movzwl 0x84(%rsp),%eax
49ed: 00
49ee: 45 09 e1 or %r12d,%r9d
49f1: 45 0f b6 c9 movzbl %r9b,%r9d
49f5: 89 74 24 10 mov %esi,0x10(%rsp)
49f9: 48 8b 74 24 78 mov 0x78(%rsp),%rsi
49fe: 89 44 24 18 mov %eax,0x18(%rsp)
4a02: 0f b6 84 24 87 00 00 movzbl 0x87(%rsp),%eax
4a09: 00
4a0a: 89 04 24 mov %eax,(%rsp)
4a0d: e8 00 00 00 00 callq 4a12 <vxlan_xmit_one+0x7f2>
4a12: e9 00 f9 ff ff jmpq 4317 <vxlan_xmit_one+0xf7>
4a17: b8 0a 00 00 00 mov $0xa,%eax
4a1c: 49 8b 54 24 20 mov 0x20(%r12),%rdx
4a21: 66 89 84 24 a0 00 00 mov %ax,0xa0(%rsp)
4a28: 00
4a29: 49 8b 44 24 18 mov 0x18(%r12),%rax
4a2e: 48 89 94 24 b0 00 00 mov %rdx,0xb0(%rsp)
4a35: 00
4a36: 48 89 84 24 a8 00 00 mov %rax,0xa8(%rsp)
4a3d: 00
4a3e: 49 8b 44 24 08 mov 0x8(%r12),%rax
4a43: 49 8b 54 24 10 mov 0x10(%r12),%rdx
dev->name);
goto drop;
}
dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
vni = vxlan_tun_id_to_vni(info->key.tun_id);
remote_ip.sa.sa_family = ip_tunnel_info_af(info);
4a48: 48 89 84 24 c8 00 00 mov %rax,0xc8(%rsp)
4a4f: 00
if (remote_ip.sa.sa_family == AF_INET) {
remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
local_ip.sin.sin_addr.s_addr = info->key.u.ipv4.src;
} else {
remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst;
4a50: b8 0a 00 00 00 mov $0xa,%eax
dev->name);
goto drop;
}
dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
vni = vxlan_tun_id_to_vni(info->key.tun_id);
remote_ip.sa.sa_family = ip_tunnel_info_af(info);
4a55: 48 89 94 24 d0 00 00 mov %rdx,0xd0(%rsp)
4a5c: 00
if (remote_ip.sa.sa_family == AF_INET) {
remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
local_ip.sin.sin_addr.s_addr = info->key.u.ipv4.src;
} else {
remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst;
4a5d: e9 5f fc ff ff jmpq 46c1 <vxlan_xmit_one+0x4a1>
4a62: 41 8b 85 b4 00 00 00 mov 0xb4(%r13),%eax
4a69: c6 44 24 48 00 movb $0x0,0x48(%rsp)
local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
4a6e: 89 84 24 94 00 00 00 mov %eax,0x94(%rsp)
4a75: 48 8d 84 24 94 00 00 lea 0x94(%rsp),%rax
4a7c: 00
4a7d: 48 89 44 24 40 mov %rax,0x40(%rsp)
4a82: e9 b0 fa ff ff jmpq 4537 <vxlan_xmit_one+0x317>
4a87: 4c 89 f7 mov %r14,%rdi
4a8a: e8 00 00 00 00 callq 4a8f <vxlan_xmit_one+0x86f>
4a8f: 88 84 24 87 00 00 00 mov %al,0x87(%rsp)
udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
if (info->options_len)
md = ip_tunnel_info_opts(info);
} else {
md->gbp = skb->mark;
4a96: e9 9a fc ff ff jmpq 4735 <vxlan_xmit_one+0x515>
__be32 vni, label;
__be16 df = 0;
__u8 tos, ttl;
int err;
u32 flags = vxlan->flags;
bool udp_sum = false;
4a9b: 48 8b 44 24 38 mov 0x38(%rsp),%rax
udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
if (info->options_len)
md = ip_tunnel_info_opts(info);
} else {
md->gbp = skb->mark;
4aa0: 44 0f b6 60 01 movzbl 0x1(%rax),%r12d
const struct iphdr *old_iph;
union vxlan_addr *dst;
union vxlan_addr remote_ip, local_ip;
union vxlan_addr *src;
struct vxlan_metadata _md;
struct vxlan_metadata *md = &_md;
4aa5: 44 0f b6 bc 24 88 00 movzbl 0x88(%rsp),%r15d
4aac: 00 00
4aae: 41 83 e4 03 and $0x3,%r12d
4ab2: b8 02 00 00 00 mov $0x2,%eax
if (!info)
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip6_dst_hoplimit(ndst);
4ab7: 41 83 e7 fc and $0xfffffffc,%r15d
4abb: 41 80 fc 03 cmp $0x3,%r12b
4abf: 44 0f 44 e0 cmove %eax,%r12d
4ac3: e9 5f fc ff ff jmpq 4727 <vxlan_xmit_one+0x507>
4ac8: 4c 89 f7 mov %r14,%rdi
/* Extract dsfield from inner protocol */
static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
const struct sk_buff *skb)
{
if (skb->protocol == htons(ETH_P_IP))
return iph->tos;
4acb: e8 00 00 00 00 callq 4ad0 <vxlan_xmit_one+0x8b0>
4ad0: e9 42 f8 ff ff jmpq 4317 <vxlan_xmit_one+0xf7>
4ad5: 45 31 ed xor %r13d,%r13d
4ad8: 4c 89 d7 mov %r10,%rdi
4adb: e8 00 00 00 00 callq 4ae0 <vxlan_xmit_one+0x8c0>
4ae0: 48 83 83 58 01 00 00 addq $0x1,0x158(%rbx)
4ae7: 01
4ae8: e9 22 f8 ff ff jmpq 430f <vxlan_xmit_one+0xef>
4aed: 48 8b 44 24 38 mov 0x38(%rsp),%rax
4af2: 44 0f b7 20 movzwl (%rax),%r12d
4af6: 66 41 c1 c4 08 rol $0x8,%r12w
skb_scrub_packet(skb, xnet);
err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
vni, md, flags, udp_sum);
if (err < 0) {
dst_release(ndst);
4afb: 66 41 c1 ec 04 shr $0x4,%r12w
return;
4b00: 0f b6 84 24 88 00 00 movzbl 0x88(%rsp),%eax
4b07: 00
{
/* dst_release() accepts a NULL parameter.
* We rely on dst being first structure in struct rtable
*/
BUILD_BUG_ON(offsetof(struct rtable, dst) != 0);
dst_release(&rt->dst);
4b08: 41 83 e4 03 and $0x3,%r12d
4b0c: 41 b9 02 00 00 00 mov $0x2,%r9d
/* skb is already freed. */
skb = NULL;
rt_tx_error:
ip_rt_put(rt);
tx_error:
dev->stats.tx_errors++;
4b12: 83 e0 fc and $0xfffffffc,%eax
4b15: 41 80 fc 03 cmp $0x3,%r12b
4b19: 88 84 24 80 00 00 00 mov %al,0x80(%rsp)
4b20: 45 0f 44 e1 cmove %r9d,%r12d
4b24: e9 11 fe ff ff jmpq 493a <vxlan_xmit_one+0x71a>
4b29: 31 d2 xor %edx,%edx
4b2b: e9 6a fa ff ff jmpq 459a <vxlan_xmit_one+0x37a>
4b30: 4d 85 db test %r11,%r11
4b33: 0f 85 24 01 00 00 jne 4c5d <vxlan_xmit_one+0xa3d>
4b39: 80 3d 00 00 00 00 00 cmpb $0x0,0x0(%rip) # 4b40 <vxlan_xmit_one+0x920>
4b40: 0f 85 c1 f7 ff ff jne 4307 <vxlan_xmit_one+0xe7>
4b46: 48 89 d9 mov %rbx,%rcx
4b49: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
4b50: be 9b 07 00 00 mov $0x79b,%esi
4b55: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
if (!vxlan->vn6_sock)
goto drop;
sk = vxlan->vn6_sock->sock->sk;
ndst = vxlan6_get_route(vxlan, skb,
4b5c: c6 05 00 00 00 00 01 movb $0x1,0x0(%rip) # 4b63 <vxlan_xmit_one+0x943>
bool udp_sum = false;
bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
info = skb_tunnel_info(skb);
if (rdst) {
4b63: e8 00 00 00 00 callq 4b68 <vxlan_xmit_one+0x948>
4b68: e9 9a f7 ff ff jmpq 4307 <vxlan_xmit_one+0xe7>
dst = &rdst->remote_ip;
src = &vxlan->cfg.saddr;
dst_cache = &rdst->dst_cache;
} else {
if (!info) {
WARN_ONCE(1, "%s: Missing encapsulation instructions\n",
4b6d: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
4b72: 4c 89 f7 mov %r14,%rdi
4b75: e8 00 00 00 00 callq 4b7a <vxlan_xmit_one+0x95a>
4b7a: 48 83 83 78 01 00 00 addq $0x1,0x178(%rbx)
4b81: 01
4b82: e9 59 ff ff ff jmpq 4ae0 <vxlan_xmit_one+0x8c0>
4b87: 48 8b 44 24 38 mov 0x38(%rsp),%rax
4b8c: 44 0f b7 20 movzwl (%rax),%r12d
4b90: 66 41 c1 c4 08 rol $0x8,%r12w
4b95: 66 41 c1 ec 04 shr $0x4,%r12w
4b9a: e9 06 ff ff ff jmpq 4aa5 <vxlan_xmit_one+0x885>
4b9f: 48 8b 44 24 38 mov 0x38(%rsp),%rax
}
if (ndst->dev == dev) {
netdev_dbg(dev, "circular route to %pI6\n",
&dst->sin6.sin6_addr);
dst_release(ndst);
4ba4: 0f b6 40 01 movzbl 0x1(%rax),%eax
4ba8: 88 84 24 88 00 00 00 mov %al,0x88(%rsp)
dev->stats.collisions++;
4baf: e9 e9 f7 ff ff jmpq 439d <vxlan_xmit_one+0x17d>
goto tx_error;
4bb4: 4c 89 f7 mov %r14,%rdi
4bb7: e8 00 00 00 00 callq 4bbc <vxlan_xmit_one+0x99c>
4bbc: 0f b7 8c 24 84 00 00 movzwl 0x84(%rsp),%ecx
4bc3: 00
4bc4: 41 0f b7 17 movzwl (%r15),%edx
4bc8: 48 8b bb 78 08 00 00 mov 0x878(%rbx),%rdi
4bcf: 44 8b 83 d8 08 00 00 mov 0x8d8(%rbx),%r8d
4bd6: 8b 74 24 50 mov 0x50(%rsp),%esi
4bda: e8 91 b5 ff ff callq 170 <vxlan_find_vni>
4bdf: 48 85 c0 test %rax,%rax
4be2: 0f 84 f8 fe ff ff je 4ae0 <vxlan_xmit_one+0x8c0>
rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
if (!info && rt6i_flags & RTF_LOCAL &&
!(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
struct vxlan_dev *dst_vxlan;
dst_release(ndst);
4be8: 48 8b b3 70 08 00 00 mov 0x870(%rbx),%rsi
dst_vxlan = vxlan_find_vni(vxlan->net, vni,
4bef: 48 89 c2 mov %rax,%rdx
4bf2: 4c 89 ef mov %r13,%rdi
4bf5: e8 46 ee ff ff callq 3a40 <vxlan_encap_bypass.isra.47>
4bfa: e9 18 f7 ff ff jmpq 4317 <vxlan_xmit_one+0xf7>
4bff: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
4c04: 48 83 83 b8 01 00 00 addq $0x1,0x1b8(%rbx)
4c0b: 01
4c0c: e9 cf fe ff ff jmpq 4ae0 <vxlan_xmit_one+0x8c0>
dst->sa.sa_family, dst_port,
vxlan->flags);
if (!dst_vxlan)
4c11: 48 8b 4c 24 68 mov 0x68(%rsp),%rcx
4c16: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
goto tx_error;
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
4c1d: 48 89 de mov %rbx,%rsi
4c20: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
4c27: e8 00 00 00 00 callq 4c2c <vxlan_xmit_one+0xa0c>
return;
4c2c: eb d6 jmp 4c04 <vxlan_xmit_one+0x9e4>
4c2e: 48 8b 44 24 38 mov 0x38(%rsp),%rax
4c33: 44 0f b6 60 01 movzbl 0x1(%rax),%r12d
&src->sin6.sin6_addr,
dst_cache, info);
if (IS_ERR(ndst)) {
netdev_dbg(dev, "no route to %pI6\n",
&dst->sin6.sin6_addr);
dev->stats.tx_carrier_errors++;
4c38: e9 c3 fe ff ff jmpq 4b00 <vxlan_xmit_one+0x8e0>
goto tx_error;
4c3d: 48 8b 4c 24 68 mov 0x68(%rsp),%rcx
rdst ? rdst->remote_ifindex : 0, tos,
label, &dst->sin6.sin6_addr,
&src->sin6.sin6_addr,
dst_cache, info);
if (IS_ERR(ndst)) {
netdev_dbg(dev, "no route to %pI6\n",
4c42: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
4c49: 48 89 de mov %rbx,%rsi
4c4c: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
4c53: e8 00 00 00 00 callq 4c58 <vxlan_xmit_one+0xa38>
4c58: e9 15 ff ff ff jmpq 4b72 <vxlan_xmit_one+0x952>
4c5d: 45 31 e4 xor %r12d,%r12d
4c60: e9 4e f6 ff ff jmpq 42b3 <vxlan_xmit_one+0x93>
4c65: 31 d2 xor %edx,%edx
4c67: e9 52 fc ff ff jmpq 48be <vxlan_xmit_one+0x69e>
4c6c: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
dev->stats.tx_carrier_errors++;
goto tx_error;
}
if (ndst->dev == dev) {
netdev_dbg(dev, "circular route to %pI6\n",
4c71: 48 83 83 78 01 00 00 addq $0x1,0x178(%rbx)
4c78: 01
4c79: e9 5a fe ff ff jmpq 4ad8 <vxlan_xmit_one+0x8b8>
4c7e: 8b 80 a4 00 00 00 mov 0xa4(%rax),%eax
4c84: 85 c0 test %eax,%eax
4c86: 78 71 js 4cf9 <vxlan_xmit_one+0xad9>
4c88: 8b 44 24 64 mov 0x64(%rsp),%eax
4c8c: 45 31 f6 xor %r14d,%r14d
bool udp_sum = false;
bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
info = skb_tunnel_info(skb);
if (rdst) {
4c8f: c1 e8 06 shr $0x6,%eax
4c92: 83 f0 01 xor $0x1,%eax
if (dst->sa.sa_family == AF_INET) {
if (!vxlan->vn4_sock)
goto drop;
sk = vxlan->vn4_sock->sock->sk;
rt = vxlan_get_route(vxlan, skb,
4c95: 83 e0 01 and $0x1,%eax
4c98: 88 44 24 48 mov %al,0x48(%rsp)
4c9c: e9 67 fc ff ff jmpq 4908 <vxlan_xmit_one+0x6e8>
}
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to %pI4\n",
&dst->sin.sin_addr.s_addr);
dev->stats.collisions++;
4ca1: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
4ca6: e9 59 ff ff ff jmpq 4c04 <vxlan_xmit_one+0x9e4>
goto rt_tx_error;
4cab: 49 8d 4f 04 lea 0x4(%r15),%rcx
}
/* Bypass encapsulation if the destination is local */
if (!info && rt->rt_flags & RTCF_LOCAL &&
4caf: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
4cb6: 48 89 de mov %rbx,%rsi
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
return;
}
if (!info)
udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
4cb9: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
4cc0: e8 00 00 00 00 callq 4cc5 <vxlan_xmit_one+0xaa5>
4cc5: e9 3a ff ff ff jmpq 4c04 <vxlan_xmit_one+0x9e4>
4cca: 49 8d 4f 04 lea 0x4(%r15),%rcx
4cce: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
4cd5: 48 89 de mov %rbx,%rsi
4cd8: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
rdst ? rdst->remote_ifindex : 0, tos,
dst->sin.sin_addr.s_addr,
&src->sin.sin_addr.s_addr,
dst_cache, info);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to %pI4\n",
4cdf: 48 89 84 24 88 00 00 mov %rax,0x88(%rsp)
4ce6: 00
4ce7: e8 00 00 00 00 callq 4cec <vxlan_xmit_one+0xacc>
4cec: 4c 8b 94 24 88 00 00 mov 0x88(%rsp),%r10
4cf3: 00
4cf4: e9 78 ff ff ff jmpq 4c71 <vxlan_xmit_one+0xa51>
4cf9: a9 00 00 00 30 test $0x30000000,%eax
dev->stats.tx_carrier_errors++;
goto tx_error;
}
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to %pI4\n",
4cfe: 4c 89 d7 mov %r10,%rdi
4d01: 75 85 jne 4c88 <vxlan_xmit_one+0xa68>
4d03: e9 af fe ff ff jmpq 4bb7 <vxlan_xmit_one+0x997>
4d08: e8 00 00 00 00 callq 4d0d <vxlan_xmit_one+0xaed>
4d0d: 0f 1f 00 nopl (%rax)
0000000000004d10 <vxlan_fill_metadata_dst>:
4d10: e8 00 00 00 00 callq 4d15 <vxlan_fill_metadata_dst+0x5>
4d15: 55 push %rbp
4d16: 48 89 f9 mov %rdi,%rcx
4d19: 48 89 e5 mov %rsp,%rbp
4d1c: 41 57 push %r15
4d1e: 41 56 push %r14
4d20: 41 55 push %r13
4d22: 41 54 push %r12
4d24: 49 89 f4 mov %rsi,%r12
4d27: 53 push %rbx
4d28: 4c 8d af 40 08 00 00 lea 0x840(%rdi),%r13
4d2f: 48 83 ec 30 sub $0x30,%rsp
dev->stats.collisions++;
goto rt_tx_error;
}
/* Bypass encapsulation if the destination is local */
if (!info && rt->rt_flags & RTCF_LOCAL &&
4d33: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
4d3a: 00 00
ip_rt_put(rt);
tx_error:
dev->stats.tx_errors++;
tx_free:
dev_kfree_skb(skb);
}
4d3c: 48 89 45 d0 mov %rax,-0x30(%rbp)
dst->remote_ifindex);
return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
}
static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
{
4d40: 31 c0 xor %eax,%eax
4d42: 48 8b 46 58 mov 0x58(%rsi),%rax
4d46: 48 83 e0 fe and $0xfffffffffffffffe,%rax
4d4a: 0f 84 6c 02 00 00 je 4fbc <vxlan_fill_metadata_dst+0x2ac>
4d50: f6 40 61 02 testb $0x2,0x61(%rax)
4d54: 48 8d 98 a0 00 00 00 lea 0xa0(%rax),%rbx
4d5b: 0f 84 3f 02 00 00 je 4fa0 <vxlan_fill_metadata_dst+0x290>
4d61: 0f b7 91 80 09 00 00 movzwl 0x980(%rcx),%edx
4d68: 0f b7 81 7e 09 00 00 movzwl 0x97e(%rcx),%eax
4d6f: 48 8b b9 80 04 00 00 mov 0x480(%rcx),%rdi
static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
{
struct metadata_dst *md_dst = (struct metadata_dst *) skb_dst(skb);
if (md_dst && md_dst->dst.flags & DST_METADATA)
4d76: 39 c2 cmp %eax,%edx
4d78: 89 45 c8 mov %eax,-0x38(%rbp)
4d7b: 89 55 cc mov %edx,-0x34(%rbp)
4d7e: 0f 8e e3 01 00 00 jle 4f67 <vxlan_fill_metadata_dst+0x257>
{
struct metadata_dst *md_dst = skb_metadata_dst(skb);
struct dst_entry *dst;
if (md_dst)
return &md_dst->u.tun_info;
4d84: 41 f6 84 24 91 00 00 testb $0x30,0x91(%r12)
4d8b: 00 30
static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
{
struct metadata_dst *md_dst = (struct metadata_dst *) skb_dst(skb);
if (md_dst && md_dst->dst.flags & DST_METADATA)
4d8d: 0f 84 f8 01 00 00 je 4f8b <vxlan_fill_metadata_dst+0x27b>
struct vxlan_dev *vxlan = netdev_priv(dev);
struct ip_tunnel_info *info = skb_tunnel_info(skb);
__be16 sport, dport;
sport = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
4d93: 41 8b 84 24 a4 00 00 mov 0xa4(%r12),%eax
4d9a: 00
4d9b: 85 c0 test %eax,%eax
4d9d: 0f 85 d1 00 00 00 jne 4e74 <vxlan_fill_metadata_dst+0x164>
4da3: 4d 8b 84 24 d8 00 00 mov 0xd8(%r12),%r8
4daa: 00
static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
int min, int max, bool use_eth)
{
u32 hash;
if (min >= max) {
4dab: 45 0f b7 8c 24 c0 00 movzwl 0xc0(%r12),%r9d
4db2: 00 00
data, proto, nhoff, hlen, flags);
}
static inline __u32 skb_get_hash(struct sk_buff *skb)
{
if (!skb->l4_hash && !skb->sw_hash)
4db4: 41 0f b6 50 0b movzbl 0xb(%r8),%edx
4db9: 41 0f b6 78 08 movzbl 0x8(%r8),%edi
4dbe: 41 0f b6 40 0a movzbl 0xa(%r8),%eax
__skb_get_hash(skb);
return skb->hash;
4dc3: 41 81 e9 05 41 52 21 sub $0x21524105,%r9d
4dca: 44 01 cf add %r9d,%edi
/* Use default range */
inet_get_local_port_range(net, &min, &max);
}
hash = skb_get_hash(skb);
if (unlikely(!hash)) {
4dcd: c1 e2 18 shl $0x18,%edx
4dd0: 8d 34 3a lea (%rdx,%rdi,1),%esi
if (use_eth) {
/* Can't find a normal hash, caller has indicated an
* Ethernet packet so use that to compute a hash.
*/
hash = jhash(skb->data, 2 * ETH_ALEN,
4dd3: c1 e0 10 shl $0x10,%eax
4dd6: 41 0f b6 78 06 movzbl 0x6(%r8),%edi
{
u32 a, b, c;
const u8 *k = key;
/* Set up the internal state */
a = b = c = JHASH_INITVAL + length + initval;
4ddb: 8d 14 06 lea (%rsi,%rax,1),%edx
4dde: 41 0f b6 40 07 movzbl 0x7(%r8),%eax
4de3: 41 0f b6 70 04 movzbl 0x4(%r8),%esi
4de8: c1 e7 10 shl $0x10,%edi
4deb: 44 01 ce add %r9d,%esi
4dee: c1 e0 18 shl $0x18,%eax
4df1: 01 f0 add %esi,%eax
4df3: 41 0f b6 30 movzbl (%r8),%esi
4df7: 01 f8 add %edi,%eax
4df9: 41 0f b6 78 05 movzbl 0x5(%r8),%edi
4dfe: 44 01 ce add %r9d,%esi
4e01: 45 0f b6 48 03 movzbl 0x3(%r8),%r9d
4e06: c1 e7 08 shl $0x8,%edi
4e09: 01 c7 add %eax,%edi
4e0b: 44 89 c8 mov %r9d,%eax
4e0e: c1 e0 18 shl $0x18,%eax
4e11: 44 8d 0c 06 lea (%rsi,%rax,1),%r9d
4e15: 41 0f b6 70 02 movzbl 0x2(%r8),%esi
4e1a: 41 0f b6 40 09 movzbl 0x9(%r8),%eax
4e1f: c1 e6 10 shl $0x10,%esi
4e22: c1 e0 08 shl $0x8,%eax
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4e25: 41 01 f1 add %esi,%r9d
4e28: 41 0f b6 70 01 movzbl 0x1(%r8),%esi
case 10: c += (u32)k[9]<<8;
case 9: c += k[8];
case 8: b += (u32)k[7]<<24;
case 7: b += (u32)k[6]<<16;
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
4e2d: 01 d0 add %edx,%eax
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4e2f: 89 fa mov %edi,%edx
4e31: 31 f8 xor %edi,%eax
4e33: c1 c2 0e rol $0xe,%edx
case 10: c += (u32)k[9]<<8;
case 9: c += k[8];
case 8: b += (u32)k[7]<<24;
case 7: b += (u32)k[6]<<16;
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
4e36: 29 d0 sub %edx,%eax
4e38: c1 e6 08 shl $0x8,%esi
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4e3b: 44 01 ce add %r9d,%esi
4e3e: 89 f2 mov %esi,%edx
4e40: 89 c6 mov %eax,%esi
4e42: 31 c2 xor %eax,%edx
4e44: c1 c6 0b rol $0xb,%esi
4e47: 29 f2 sub %esi,%edx
4e49: 31 d7 xor %edx,%edi
__jhash_final(a, b, c);
4e4b: 89 fe mov %edi,%esi
4e4d: 89 d7 mov %edx,%edi
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4e4f: c1 cf 07 ror $0x7,%edi
__jhash_final(a, b, c);
4e52: 29 fe sub %edi,%esi
4e54: 89 f7 mov %esi,%edi
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4e56: 31 f0 xor %esi,%eax
4e58: c1 c7 10 rol $0x10,%edi
4e5b: 29 f8 sub %edi,%eax
__jhash_final(a, b, c);
4e5d: 89 c7 mov %eax,%edi
4e5f: 31 c2 xor %eax,%edx
4e61: c1 c7 04 rol $0x4,%edi
4e64: 29 fa sub %edi,%edx
4e66: 31 d6 xor %edx,%esi
case 6: b += (u32)k[5]<<8;
case 5: b += k[4];
case 4: a += (u32)k[3]<<24;
case 3: a += (u32)k[2]<<16;
case 2: a += (u32)k[1]<<8;
case 1: a += k[0];
4e68: c1 c2 0e rol $0xe,%edx
4e6b: 29 d6 sub %edx,%esi
4e6d: 31 f0 xor %esi,%eax
__jhash_final(a, b, c);
4e6f: c1 ce 08 ror $0x8,%esi
4e72: 29 f0 sub %esi,%eax
4e74: 8b 75 c8 mov -0x38(%rbp),%esi
4e77: 44 8b 75 cc mov -0x34(%rbp),%r14d
4e7b: 89 c2 mov %eax,%edx
4e7d: c1 e2 10 shl $0x10,%edx
4e80: 44 0f b7 7b 32 movzwl 0x32(%rbx),%r15d
4e85: 31 d0 xor %edx,%eax
4e87: 41 29 f6 sub %esi,%r14d
4e8a: 4d 63 f6 movslq %r14d,%r14
4e8d: 49 0f af c6 imul %r14,%rax
4e91: 48 c1 e8 20 shr $0x20,%rax
4e95: 44 8d 34 30 lea (%rax,%rsi,1),%r14d
4e99: 66 41 c1 c6 08 rol $0x8,%r14w
4e9e: 66 45 85 ff test %r15w,%r15w
4ea2: 75 08 jne 4eac <vxlan_fill_metadata_dst+0x19c>
* attacker is leaked. Only upper 16 bits are relevant in the
* computation for 16 bit port value.
*/
hash ^= hash << 16;
return htons((((u64) hash * (max - min)) >> 32) + min);
4ea4: 44 0f b7 b9 7c 09 00 movzwl 0x97c(%rcx),%r15d
4eab: 00
/* Since this is being sent on the wire obfuscate hash a bit
* to minimize possbility that any useful information to an
* attacker is leaked. Only upper 16 bits are relevant in the
* computation for 16 bit port value.
*/
hash ^= hash << 16;
4eac: f6 43 49 02 testb $0x2,0x49(%rbx)
vxlan->cfg.port_max, true);
dport = info->key.tp_dst ? : vxlan->cfg.dst_port;
4eb0: 75 3e jne 4ef0 <vxlan_fill_metadata_dst+0x1e0>
4eb2: 48 83 b9 60 08 00 00 cmpq $0x0,0x860(%rcx)
4eb9: 00
return htons((((u64) hash * (max - min)) >> 32) + min);
4eba: 0f 84 03 01 00 00 je 4fc3 <vxlan_fill_metadata_dst+0x2b3>
4ec0: 0f b6 4b 2a movzbl 0x2a(%rbx),%ecx
4ec4: 44 8b 43 0c mov 0xc(%rbx),%r8d
4ec8: 4c 8d 4b 08 lea 0x8(%rbx),%r9
4ecc: 31 d2 xor %edx,%edx
4ece: 48 89 5c 24 08 mov %rbx,0x8(%rsp)
4ed3: 48 c7 04 24 00 00 00 movq $0x0,(%rsp)
4eda: 00
4edb: 4c 89 e6 mov %r12,%rsi
}
static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
*tun_info)
{
return tun_info->mode & IP_TUNNEL_INFO_IPV6 ? AF_INET6 : AF_INET;
4ede: 4c 89 ef mov %r13,%rdi
4ee1: e8 1a e7 ff ff callq 3600 <vxlan_get_route>
if (ip_tunnel_info_af(info) == AF_INET) {
struct rtable *rt;
if (!vxlan->vn4_sock)
4ee6: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
4eec: 76 47 jbe 4f35 <vxlan_fill_metadata_dst+0x225>
4eee: eb 59 jmp 4f49 <vxlan_fill_metadata_dst+0x239>
return -EINVAL;
rt = vxlan_get_route(vxlan, skb, 0, info->key.tos,
4ef0: 48 83 b9 68 08 00 00 cmpq $0x0,0x868(%rcx)
4ef7: 00
4ef8: 0f 84 c5 00 00 00 je 4fc3 <vxlan_fill_metadata_dst+0x2b3>
4efe: 0f b6 4b 2a movzbl 0x2a(%rbx),%ecx
4f02: 44 8b 43 2c mov 0x2c(%rbx),%r8d
4f06: 48 8d 43 08 lea 0x8(%rbx),%rax
4f0a: 4c 8d 4b 18 lea 0x18(%rbx),%r9
4f0e: 31 d2 xor %edx,%edx
4f10: 48 89 5c 24 10 mov %rbx,0x10(%rsp)
4f15: 48 c7 44 24 08 00 00 movq $0x0,0x8(%rsp)
4f1c: 00 00
info->key.u.ipv4.dst,
&info->key.u.ipv4.src, NULL, info);
if (IS_ERR(rt))
4f1e: 48 89 04 24 mov %rax,(%rsp)
ip_rt_put(rt);
} else {
#if IS_ENABLED(CONFIG_IPV6)
struct dst_entry *ndst;
if (!vxlan->vn6_sock)
4f22: 4c 89 e6 mov %r12,%rsi
4f25: 4c 89 ef mov %r13,%rdi
4f28: e8 43 bb ff ff callq a70 <vxlan6_get_route>
4f2d: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
return -EINVAL;
ndst = vxlan6_get_route(vxlan, skb, 0, info->key.tos,
4f33: 77 14 ja 4f49 <vxlan_fill_metadata_dst+0x239>
4f35: 48 89 c7 mov %rax,%rdi
4f38: e8 00 00 00 00 callq 4f3d <vxlan_fill_metadata_dst+0x22d>
4f3d: 66 44 89 73 30 mov %r14w,0x30(%rbx)
4f42: 66 44 89 7b 32 mov %r15w,0x32(%rbx)
4f47: 31 c0 xor %eax,%eax
4f49: 48 8b 5d d0 mov -0x30(%rbp),%rbx
4f4d: 65 48 33 1c 25 28 00 xor %gs:0x28,%rbx
4f54: 00 00
4f56: 75 75 jne 4fcd <vxlan_fill_metadata_dst+0x2bd>
4f58: 48 83 c4 30 add $0x30,%rsp
4f5c: 5b pop %rbx
info->key.label, &info->key.u.ipv6.dst,
&info->key.u.ipv6.src, NULL, info);
if (IS_ERR(ndst))
4f5d: 41 5c pop %r12
4f5f: 41 5d pop %r13
4f61: 41 5e pop %r14
4f63: 41 5f pop %r15
return PTR_ERR(ndst);
dst_release(ndst);
4f65: 5d pop %rbp
4f66: c3 retq
4f67: 48 8d 55 cc lea -0x34(%rbp),%rdx
4f6b: 48 8d 75 c8 lea -0x38(%rbp),%rsi
#else /* !CONFIG_IPV6 */
return -EPFNOSUPPORT;
#endif
}
info->key.tp_src = sport;
4f6f: 48 89 4d c0 mov %rcx,-0x40(%rbp)
info->key.tp_dst = dport;
4f73: e8 00 00 00 00 callq 4f78 <vxlan_fill_metadata_dst+0x268>
return 0;
4f78: 41 f6 84 24 91 00 00 testb $0x30,0x91(%r12)
4f7f: 00 30
}
4f81: 48 8b 4d c0 mov -0x40(%rbp),%rcx
4f85: 0f 85 08 fe ff ff jne 4d93 <vxlan_fill_metadata_dst+0x83>
4f8b: 4c 89 e7 mov %r12,%rdi
4f8e: 48 89 4d c0 mov %rcx,-0x40(%rbp)
4f92: e8 00 00 00 00 callq 4f97 <vxlan_fill_metadata_dst+0x287>
{
u32 hash;
if (min >= max) {
/* Use default range */
inet_get_local_port_range(net, &min, &max);
4f97: 48 8b 4d c0 mov -0x40(%rbp),%rcx
4f9b: e9 f3 fd ff ff jmpq 4d93 <vxlan_fill_metadata_dst+0x83>
4fa0: 48 8b 80 90 00 00 00 mov 0x90(%rax),%rax
4fa7: 48 8d 58 1c lea 0x1c(%rax),%rbx
data, proto, nhoff, hlen, flags);
}
static inline __u32 skb_get_hash(struct sk_buff *skb)
{
if (!skb->l4_hash && !skb->sw_hash)
4fab: 48 85 c0 test %rax,%rax
4fae: b8 00 00 00 00 mov $0x0,%eax
4fb3: 48 0f 44 d8 cmove %rax,%rbx
4fb7: e9 a5 fd ff ff jmpq 4d61 <vxlan_fill_metadata_dst+0x51>
__skb_get_hash(skb);
4fbc: 31 db xor %ebx,%ebx
4fbe: e9 9e fd ff ff jmpq 4d61 <vxlan_fill_metadata_dst+0x51>
4fc3: b8 ea ff ff ff mov $0xffffffea,%eax
4fc8: e9 7c ff ff ff jmpq 4f49 <vxlan_fill_metadata_dst+0x239>
4fcd: e8 00 00 00 00 callq 4fd2 <vxlan_fill_metadata_dst+0x2c2>
if (md_dst)
return &md_dst->u.tun_info;
dst = skb_dst(skb);
if (dst && dst->lwtstate)
4fd2: 0f 1f 40 00 nopl 0x0(%rax)
4fd6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4fdd: 00 00 00
0000000000004fe0 <vxlan_gro_receive>:
info->options_len = len;
}
static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstate)
{
return (struct ip_tunnel_info *)lwtstate->data;
4fe0: e8 00 00 00 00 callq 4fe5 <vxlan_gro_receive+0x5>
4fe5: 55 push %rbp
4fe6: 49 89 f0 mov %rsi,%r8
4fe9: 48 89 e5 mov %rsp,%rbp
return lwt_tun_info(dst->lwtstate);
return NULL;
4fec: 41 57 push %r15
4fee: 41 56 push %r14
4ff0: 41 55 push %r13
4ff2: 41 54 push %r12
if (ip_tunnel_info_af(info) == AF_INET) {
struct rtable *rt;
if (!vxlan->vn4_sock)
return -EINVAL;
4ff4: 53 push %rbx
4ff5: 48 89 d3 mov %rdx,%rbx
4ff8: 48 83 ec 20 sub $0x20,%rsp
4ffc: 8b 4a 34 mov 0x34(%rdx),%ecx
#endif
}
info->key.tp_src = sport;
info->key.tp_dst = dport;
return 0;
}
4fff: 4c 8b b7 48 02 00 00 mov 0x248(%rdi),%r14
5006: 44 8d 61 08 lea 0x8(%rcx),%r12d
500a: 44 39 62 30 cmp %r12d,0x30(%rdx)
500e: 49 89 cd mov %rcx,%r13
}
static struct sk_buff **vxlan_gro_receive(struct sock *sk,
struct sk_buff **head,
struct sk_buff *skb)
{
5011: 73 50 jae 5063 <vxlan_gro_receive+0x83>
5013: 8b 92 80 00 00 00 mov 0x80(%rdx),%edx
5019: 89 d0 mov %edx,%eax
501b: 2b 83 84 00 00 00 sub 0x84(%rbx),%eax
5021: 41 39 c4 cmp %eax,%r12d
5024: 0f 87 ab 02 00 00 ja 52d5 <vxlan_gro_receive+0x2f5>
502a: 49 89 cf mov %rcx,%r15
int dev_restart(struct net_device *dev);
int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb);
static inline unsigned int skb_gro_offset(const struct sk_buff *skb)
{
return NAPI_GRO_CB(skb)->data_offset;
502d: 4c 03 bb d8 00 00 00 add 0xd8(%rbx),%r15
5034: 48 c7 43 28 00 00 00 movq $0x0,0x28(%rbx)
503b: 00
skb_gro_remcsum_init(&grc);
off_vx = skb_gro_offset(skb);
hlen = off_vx + sizeof(*vh);
vh = skb_gro_header_fast(skb, off_vx);
if (skb_gro_header_hard(skb, hlen)) {
503c: c7 43 30 00 00 00 00 movl $0x0,0x30(%rbx)
5043: 75 25 jne 506a <vxlan_gro_receive+0x8a>
5045: ba 01 00 00 00 mov $0x1,%edx
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
504a: 45 31 ff xor %r15d,%r15d
504d: 66 09 53 38 or %dx,0x38(%rbx)
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
5051: 48 83 c4 20 add $0x20,%rsp
5055: 4c 89 f8 mov %r15,%rax
5058: 5b pop %rbx
5059: 41 5c pop %r12
vh = skb_gro_header_slow(skb, hlen, off_vx);
if (unlikely(!vh))
505b: 41 5d pop %r13
505d: 41 5e pop %r14
505f: 41 5f pop %r15
5061: 5d pop %rbp
5062: c3 retq
5063: 49 89 cf mov %rcx,%r15
unsigned int offset)
{
if (!pskb_may_pull(skb, hlen))
return NULL;
NAPI_GRO_CB(skb)->frag0 = NULL;
5066: 4c 03 7a 28 add 0x28(%rdx),%r15
506a: f6 43 4a 04 testb $0x4,0x4a(%rbx)
NAPI_GRO_CB(skb)->frag0_len = 0;
506e: 74 2c je 509c <vxlan_gro_receive+0xbc>
5070: 31 d2 xor %edx,%edx
5072: be 08 00 00 00 mov $0x8,%esi
static struct sk_buff **vxlan_gro_receive(struct sock *sk,
struct sk_buff **head,
struct sk_buff *skb)
{
struct sk_buff *p, **pp = NULL;
5077: 4c 89 ff mov %r15,%rdi
507a: 4c 89 45 c8 mov %r8,-0x38(%rbp)
pp = eth_gro_receive(head, skb);
flush = 0;
out:
skb_gro_remcsum_cleanup(skb, &grc);
NAPI_GRO_CB(skb)->flush |= flush;
507e: 48 89 4d d0 mov %rcx,-0x30(%rbp)
return pp;
}
5082: e8 00 00 00 00 callq 5087 <vxlan_gro_receive+0xa7>
5087: 4c 8b 45 c8 mov -0x38(%rbp),%r8
508b: 48 8b 4d d0 mov -0x30(%rbp),%rcx
508f: f7 d0 not %eax
5091: 8b 53 4c mov 0x4c(%rbx),%edx
}
static inline void *skb_gro_header_fast(struct sk_buff *skb,
unsigned int offset)
{
return NAPI_GRO_CB(skb)->frag0 + offset;
5094: 01 c2 add %eax,%edx
5096: 83 d2 00 adc $0x0,%edx
5099: 89 53 4c mov %edx,0x4c(%rbx)
}
static inline void skb_gro_postpull_rcsum(struct sk_buff *skb,
const void *start, unsigned int len)
{
if (NAPI_GRO_CB(skb)->csum_valid)
509c: 41 f7 07 00 20 00 00 testl $0x2000,(%r15)
NAPI_GRO_CB(skb)->csum = csum_sub(NAPI_GRO_CB(skb)->csum,
50a3: 0f 85 a5 00 00 00 jne 514e <vxlan_gro_receive+0x16e>
50a9: 41 bd 02 00 00 00 mov $0x2,%r13d
50af: 45 31 f6 xor %r14d,%r14d
50b2: 45 31 e4 xor %r12d,%r12d
50b5: 83 43 34 08 addl $0x8,0x34(%rbx)
50b9: 49 8b 00 mov (%r8),%rax
50bc: 48 85 c0 test %rax,%rax
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
asm("addl %2,%0\n\t"
50bf: 75 0e jne 50cf <vxlan_gro_receive+0xef>
50c1: eb 34 jmp 50f7 <vxlan_gro_receive+0x117>
50c3: 80 60 4a fe andb $0xfe,0x4a(%rax)
50c7: 48 8b 00 mov (%rax),%rax
50ca: 48 85 c0 test %rax,%rax
skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr));
flags = vh->vx_flags;
if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
50cd: 74 28 je 50f7 <vxlan_gro_receive+0x117>
50cf: f6 40 4a 01 testb $0x1,0x4a(%rax)
50d3: 74 f2 je 50c7 <vxlan_gro_receive+0xe7>
50d5: 48 89 ca mov %rcx,%rdx
50d8: 48 03 90 d8 00 00 00 add 0xd8(%rax),%rdx
};
static inline void skb_gro_remcsum_init(struct gro_remcsum *grc)
{
grc->offset = 0;
grc->delta = 0;
50df: 8b 3a mov (%rdx),%edi
50e1: 41 39 3f cmp %edi,(%r15)
__wsum delta;
};
static inline void skb_gro_remcsum_init(struct gro_remcsum *grc)
{
grc->offset = 0;
50e4: 75 dd jne 50c3 <vxlan_gro_receive+0xe3>
return skb->len - NAPI_GRO_CB(skb)->data_offset;
}
static inline void skb_gro_pull(struct sk_buff *skb, unsigned int len)
{
NAPI_GRO_CB(skb)->data_offset += len;
50e6: 8b 72 04 mov 0x4(%rdx),%esi
goto out;
}
skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
for (p = *head; p; p = p->next) {
50e9: 41 39 77 04 cmp %esi,0x4(%r15)
50ed: 75 d4 jne 50c3 <vxlan_gro_receive+0xe3>
50ef: 48 8b 00 mov (%rax),%rax
50f2: 48 85 c0 test %rax,%rax
continue;
vh2 = (struct vxlanhdr *)(p->data + off_vx);
if (vh->vx_flags != vh2->vx_flags ||
vh->vx_vni != vh2->vx_vni) {
NAPI_GRO_CB(p)->same_flow = 0;
50f5: 75 d8 jne 50cf <vxlan_gro_receive+0xef>
goto out;
}
skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
for (p = *head; p; p = p->next) {
50f7: 48 89 de mov %rbx,%rsi
50fa: 4c 89 c7 mov %r8,%rdi
50fd: e8 00 00 00 00 callq 5102 <vxlan_gro_receive+0x122>
if (!NAPI_GRO_CB(p)->same_flow)
5102: 31 d2 xor %edx,%edx
5104: 49 89 c7 mov %rax,%r15
continue;
vh2 = (struct vxlanhdr *)(p->data + off_vx);
5107: 45 85 f6 test %r14d,%r14d
510a: 0f 84 3d ff ff ff je 504d <vxlan_gro_receive+0x6d>
if (vh->vx_flags != vh2->vx_flags ||
5110: 44 89 e1 mov %r12d,%ecx
5113: 41 83 c4 02 add $0x2,%r12d
5117: 44 3b 63 30 cmp 0x30(%rbx),%r12d
511b: 0f 87 7c 01 00 00 ja 529d <vxlan_gro_receive+0x2bd>
goto out;
}
skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
for (p = *head; p; p = p->next) {
5121: 48 03 4b 28 add 0x28(%rbx),%rcx
5125: 0f b7 31 movzwl (%rcx),%esi
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
}
pp = eth_gro_receive(head, skb);
5128: 44 89 f0 mov %r14d,%eax
512b: f7 d6 not %esi
512d: 01 f0 add %esi,%eax
512f: 83 d0 00 adc $0x0,%eax
5132: 89 c6 mov %eax,%esi
5134: 66 31 c0 xor %ax,%ax
struct gro_remcsum *grc)
{
void *ptr;
size_t plen = grc->offset + sizeof(u16);
if (!grc->delta)
5137: c1 e6 10 shl $0x10,%esi
513a: 01 f0 add %esi,%eax
513c: 15 ff ff 00 00 adc $0xffff,%eax
}
static inline void *skb_gro_header_fast(struct sk_buff *skb,
unsigned int offset)
{
return NAPI_GRO_CB(skb)->frag0 + offset;
5141: f7 d0 not %eax
if (!grc->delta)
return;
ptr = skb_gro_header_fast(skb, grc->offset);
if (skb_gro_header_hard(skb, grc->offset + sizeof(u16))) {
5143: c1 e8 10 shr $0x10,%eax
5146: 66 89 01 mov %ax,(%rcx)
5149: e9 ff fe ff ff jmpq 504d <vxlan_gro_receive+0x6d>
514e: 41 8b 86 1c 20 00 00 mov 0x201c(%r14),%eax
5155: f6 c4 04 test $0x4,%ah
5158: 0f 84 4b ff ff ff je 50a9 <vxlan_gro_receive+0xc9>
515e: 0f b6 b3 93 00 00 00 movzbl 0x93(%rbx),%esi
* the last step before putting a checksum into a packet.
* Make sure not to mix with 64bit checksums.
*/
static inline __sum16 csum_fold(__wsum sum)
{
asm(" addl %1,%0\n"
5165: 40 f6 c6 10 test $0x10,%sil
5169: 0f 85 9a 01 00 00 jne 5309 <vxlan_gro_receive+0x329>
516f: f6 43 4a 04 testb $0x4,0x4a(%rbx)
return delta;
}
static inline void remcsum_unadjust(__sum16 *psum, __wsum delta)
{
*psum = csum_fold(csum_sub(delta, *psum));
5173: 0f 84 cc fe ff ff je 5045 <vxlan_gro_receive+0x65>
5179: 49 63 57 04 movslq 0x4(%r15),%rdx
517d: 41 89 d6 mov %edx,%r14d
skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr));
flags = vh->vx_flags;
if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
5180: 48 c1 fa 3f sar $0x3f,%rdx
5184: 41 81 e6 00 00 00 7f and $0x7f000000,%r14d
518b: 48 83 e2 f6 and $0xfffffffffffffff6,%rdx
struct gro_remcsum *grc,
bool nopartial)
{
size_t start, offset;
if (skb->remcsum_offload)
518f: 41 0f ce bswap %r14d
5192: 48 83 c2 10 add $0x10,%rdx
5196: 45 01 f6 add %r14d,%r14d
5199: f6 c4 10 test $0x10,%ah
519c: 0f 84 75 01 00 00 je 5317 <vxlan_gro_receive+0x337>
return vh;
if (!NAPI_GRO_CB(skb)->csum_valid)
51a2: 45 89 f1 mov %r14d,%r9d
51a5: 49 01 d1 add %rdx,%r9
51a8: 49 63 d6 movslq %r14d,%rdx
skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr));
flags = vh->vx_flags;
if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
51ab: 4d 63 d1 movslq %r9d,%r10
#endif
}
static inline size_t vxlan_rco_start(__be32 vni_field)
{
return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
51ae: 49 8d 42 02 lea 0x2(%r10),%rax
}
static inline size_t vxlan_rco_offset(__be32 vni_field)
{
return (vni_field & VXLAN_RCO_UDP) ?
offsetof(struct udphdr, check) :
51b2: 48 39 d0 cmp %rdx,%rax
#endif
}
static inline size_t vxlan_rco_start(__be32 vni_field)
{
return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
51b5: 48 0f 42 c2 cmovb %rdx,%rax
51b9: 41 8d 44 05 08 lea 0x8(%r13,%rax,1),%eax
}
static inline size_t vxlan_rco_offset(__be32 vni_field)
{
return (vni_field & VXLAN_RCO_UDP) ?
offsetof(struct udphdr, check) :
51be: 3b 43 30 cmp 0x30(%rbx),%eax
#endif
}
static inline size_t vxlan_rco_start(__be32 vni_field)
{
return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
51c1: 0f 86 72 01 00 00 jbe 5339 <vxlan_gro_receive+0x359>
51c7: 8b b3 80 00 00 00 mov 0x80(%rbx),%esi
__wsum delta;
size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
BUG_ON(!NAPI_GRO_CB(skb)->csum_valid);
if (!nopartial) {
51cd: 89 f2 mov %esi,%edx
51cf: 2b 93 84 00 00 00 sub 0x84(%rbx),%edx
if (!NAPI_GRO_CB(skb)->csum_valid)
return NULL;
start = vxlan_rco_start(vni_field);
offset = start + vxlan_rco_offset(vni_field);
51d5: 39 d0 cmp %edx,%eax
51d7: 0f 87 9a 01 00 00 ja 5377 <vxlan_gro_receive+0x397>
int start, int offset,
struct gro_remcsum *grc,
bool nopartial)
{
__wsum delta;
size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
51dd: 49 89 cf mov %rcx,%r15
NAPI_GRO_CB(skb)->gro_remcsum_start = off + hdrlen + start;
return ptr;
}
ptr = skb_gro_header_fast(skb, off);
if (skb_gro_header_hard(skb, off + plen)) {
51e0: 4c 03 bb d8 00 00 00 add 0xd8(%rbx),%r15
51e7: 48 c7 43 28 00 00 00 movq $0x0,0x28(%rbx)
51ee: 00
51ef: c7 43 30 00 00 00 00 movl $0x0,0x30(%rbx)
51f6: 0f 84 b4 01 00 00 je 53b0 <vxlan_gro_receive+0x3d0>
51fc: 49 8d 7f 08 lea 0x8(%r15),%rdi
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
5200: 31 d2 xor %edx,%edx
5202: 44 89 f6 mov %r14d,%esi
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
5205: 4c 89 45 b8 mov %r8,-0x48(%rbp)
5209: 4c 89 4d c0 mov %r9,-0x40(%rbp)
ptr = skb_gro_header_slow(skb, off + plen, off);
if (!ptr)
520d: 49 01 fa add %rdi,%r10
5210: 48 89 4d c8 mov %rcx,-0x38(%rbp)
5214: 44 8b 6b 4c mov 0x4c(%rbx),%r13d
unsigned int offset)
{
if (!pskb_may_pull(skb, hlen))
return NULL;
NAPI_GRO_CB(skb)->frag0 = NULL;
5218: 4c 89 55 d0 mov %r10,-0x30(%rbp)
521c: e8 00 00 00 00 callq 5221 <vxlan_gro_receive+0x241>
NAPI_GRO_CB(skb)->frag0_len = 0;
5221: 4c 8b 55 d0 mov -0x30(%rbp),%r10
5225: 4c 8b 4d c0 mov -0x40(%rbp),%r9
}
ptr = skb_gro_header_fast(skb, off);
if (skb_gro_header_hard(skb, off + plen)) {
ptr = skb_gro_header_slow(skb, off + plen, off);
if (!ptr)
5229: f7 d0 not %eax
522b: 41 01 c5 add %eax,%r13d
return NULL;
}
delta = remcsum_adjust(ptr + hdrlen, NAPI_GRO_CB(skb)->csum,
522e: 41 83 d5 00 adc $0x0,%r13d
{
__sum16 *psum = (__sum16 *)(ptr + offset);
__wsum delta;
/* Subtract out checksum up to start */
csum = csum_sub(csum, csum_partial(ptr, start, 0));
5232: 44 89 e8 mov %r13d,%eax
5235: 66 45 31 ed xor %r13w,%r13w
5239: 48 8b 4d c8 mov -0x38(%rbp),%rcx
}
static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
int start, int offset)
{
__sum16 *psum = (__sum16 *)(ptr + offset);
523d: 41 0f b7 12 movzwl (%r10),%edx
5241: c1 e0 10 shl $0x10,%eax
5244: 45 01 cc add %r9d,%r12d
5247: 41 01 c5 add %eax,%r13d
524a: 41 81 d5 ff ff 00 00 adc $0xffff,%r13d
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
asm("addl %2,%0\n\t"
5251: 41 f7 d5 not %r13d
5254: 4c 8b 45 b8 mov -0x48(%rbp),%r8
start, offset);
/* Adjust skb->csum since we changed the packet */
NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta);
grc->offset = off + hdrlen + offset;
5258: 41 c1 ed 10 shr $0x10,%r13d
525c: 66 45 89 2a mov %r13w,(%r10)
5260: 44 89 e8 mov %r13d,%eax
static inline __sum16 csum_fold(__wsum sum)
{
asm(" addl %1,%0\n"
" adcl $0xffff,%0"
: "=r" (sum)
: "r" ((__force u32)sum << 16),
5263: 4d 63 ec movslq %r12d,%r13
"0" ((__force u32)sum & 0xffff0000));
5266: f7 d2 not %edx
5268: 49 83 c5 02 add $0x2,%r13
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
vh->vx_vni, &grc,
!!(vs->flags &
VXLAN_F_REMCSUM_NOPARTIAL));
if (!vh)
526c: 80 8b 93 00 00 00 10 orb $0x10,0x93(%rbx)
static inline __sum16 csum_fold(__wsum sum)
{
asm(" addl %1,%0\n"
" adcl $0xffff,%0"
: "=r" (sum)
: "r" ((__force u32)sum << 16),
5273: 01 d0 add %edx,%eax
5275: 83 d0 00 adc $0x0,%eax
* the last step before putting a checksum into a packet.
* Make sure not to mix with 64bit checksums.
*/
static inline __sum16 csum_fold(__wsum sum)
{
asm(" addl %1,%0\n"
5278: 41 89 c6 mov %eax,%r14d
527b: 8b 43 4c mov 0x4c(%rbx),%eax
527e: 44 01 f0 add %r14d,%eax
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
asm("addl %2,%0\n\t"
5281: 83 d0 00 adc $0x0,%eax
5284: 4d 85 ff test %r15,%r15
5287: 89 43 4c mov %eax,0x4c(%rbx)
528a: 0f 85 25 fe ff ff jne 50b5 <vxlan_gro_receive+0xd5>
5290: ba 01 00 00 00 mov $0x1,%edx
5295: 45 31 ff xor %r15d,%r15d
5298: e9 6a fe ff ff jmpq 5107 <vxlan_gro_receive+0x127>
offset = start + vxlan_rco_offset(vni_field);
vh = skb_gro_remcsum_process(skb, (void *)vh, off, hdrlen,
start, offset, grc, nopartial);
skb->remcsum_offload = 1;
529d: 8b b3 80 00 00 00 mov 0x80(%rbx),%esi
52a3: 89 f0 mov %esi,%eax
52a5: 2b 83 84 00 00 00 sub 0x84(%rbx),%eax
52ab: 41 39 c5 cmp %eax,%r13d
52ae: 0f 87 91 00 00 00 ja 5345 <vxlan_gro_receive+0x365>
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
vh->vx_vni, &grc,
!!(vs->flags &
VXLAN_F_REMCSUM_NOPARTIAL));
if (!vh)
52b4: 48 03 8b d8 00 00 00 add 0xd8(%rbx),%rcx
52bb: 48 c7 43 28 00 00 00 movq $0x0,0x28(%rbx)
52c2: 00
52c3: c7 43 30 00 00 00 00 movl $0x0,0x30(%rbx)
static struct sk_buff **vxlan_gro_receive(struct sock *sk,
struct sk_buff **head,
struct sk_buff *skb)
{
struct sk_buff *p, **pp = NULL;
52ca: 0f 85 55 fe ff ff jne 5125 <vxlan_gro_receive+0x145>
52d0: e9 78 fd ff ff jmpq 504d <vxlan_gro_receive+0x6d>
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
52d5: 41 39 d4 cmp %edx,%r12d
52d8: 48 89 75 c8 mov %rsi,-0x38(%rbp)
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
52dc: 48 89 4d d0 mov %rcx,-0x30(%rbp)
52e0: 0f 87 5f fd ff ff ja 5045 <vxlan_gro_receive+0x65>
return;
ptr = skb_gro_header_fast(skb, grc->offset);
if (skb_gro_header_hard(skb, grc->offset + sizeof(u16))) {
ptr = skb_gro_header_slow(skb, plen, grc->offset);
if (!ptr)
52e6: 44 89 e6 mov %r12d,%esi
52e9: 48 89 df mov %rbx,%rdi
unsigned int offset)
{
if (!pskb_may_pull(skb, hlen))
return NULL;
NAPI_GRO_CB(skb)->frag0 = NULL;
52ec: 29 c6 sub %eax,%esi
52ee: e8 00 00 00 00 callq 52f3 <vxlan_gro_receive+0x313>
NAPI_GRO_CB(skb)->frag0_len = 0;
52f3: 48 85 c0 test %rax,%rax
52f6: 48 8b 4d d0 mov -0x30(%rbp),%rcx
return;
ptr = skb_gro_header_fast(skb, grc->offset);
if (skb_gro_header_hard(skb, grc->offset + sizeof(u16))) {
ptr = skb_gro_header_slow(skb, plen, grc->offset);
if (!ptr)
52fa: 4c 8b 45 c8 mov -0x38(%rbp),%r8
52fe: 0f 84 41 fd ff ff je 5045 <vxlan_gro_receive+0x65>
5304: e9 21 fd ff ff jmpq 502a <vxlan_gro_receive+0x4a>
return 1;
if (unlikely(len > skb->len))
5309: 4d 85 ff test %r15,%r15
530c: 0f 85 97 fd ff ff jne 50a9 <vxlan_gro_receive+0xc9>
5312: e9 2e fd ff ff jmpq 5045 <vxlan_gro_receive+0x65>
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
5317: 47 8d 6c 35 08 lea 0x8(%r13,%r14,1),%r13d
531c: 83 ce 10 or $0x10,%esi
531f: 4d 85 ff test %r15,%r15
5322: 40 88 b3 93 00 00 00 mov %sil,0x93(%rbx)
}
static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
unsigned int offset)
{
if (!pskb_may_pull(skb, hlen))
5329: 66 44 89 6b 3e mov %r13w,0x3e(%rbx)
532e: 0f 85 75 fd ff ff jne 50a9 <vxlan_gro_receive+0xc9>
5334: e9 0c fd ff ff jmpq 5045 <vxlan_gro_receive+0x65>
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
vh->vx_vni, &grc,
!!(vs->flags &
VXLAN_F_REMCSUM_NOPARTIAL));
if (!vh)
5339: 49 89 cf mov %rcx,%r15
533c: 4c 03 7b 28 add 0x28(%rbx),%r15
5340: e9 b7 fe ff ff jmpq 51fc <vxlan_gro_receive+0x21c>
5345: 44 39 ee cmp %r13d,%esi
size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
BUG_ON(!NAPI_GRO_CB(skb)->csum_valid);
if (!nopartial) {
NAPI_GRO_CB(skb)->gro_remcsum_start = off + hdrlen + start;
5348: 48 89 4d c8 mov %rcx,-0x38(%rbp)
offset = start + vxlan_rco_offset(vni_field);
vh = skb_gro_remcsum_process(skb, (void *)vh, off, hdrlen,
start, offset, grc, nopartial);
skb->remcsum_offload = 1;
534c: 0f 82 fb fc ff ff jb 504d <vxlan_gro_receive+0x6d>
5352: 44 89 ee mov %r13d,%esi
5355: 48 89 df mov %rbx,%rdi
5358: 89 55 d0 mov %edx,-0x30(%rbp)
535b: 29 c6 sub %eax,%esi
535d: e8 00 00 00 00 callq 5362 <vxlan_gro_receive+0x382>
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
vh->vx_vni, &grc,
!!(vs->flags &
VXLAN_F_REMCSUM_NOPARTIAL));
if (!vh)
5362: 48 85 c0 test %rax,%rax
5365: 8b 55 d0 mov -0x30(%rbp),%edx
5368: 48 8b 4d c8 mov -0x38(%rbp),%rcx
}
static inline void *skb_gro_header_fast(struct sk_buff *skb,
unsigned int offset)
{
return NAPI_GRO_CB(skb)->frag0 + offset;
536c: 0f 84 db fc ff ff je 504d <vxlan_gro_receive+0x6d>
5372: e9 3d ff ff ff jmpq 52b4 <vxlan_gro_receive+0x2d4>
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
5377: 39 f0 cmp %esi,%eax
5379: 77 35 ja 53b0 <vxlan_gro_receive+0x3d0>
537b: 29 d0 sub %edx,%eax
537d: 48 89 df mov %rbx,%rdi
5380: 4c 89 45 b8 mov %r8,-0x48(%rbp)
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
5384: 89 c6 mov %eax,%esi
5386: 4c 89 55 c0 mov %r10,-0x40(%rbp)
538a: 4c 89 4d c8 mov %r9,-0x38(%rbp)
538e: 48 89 4d d0 mov %rcx,-0x30(%rbp)
}
static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
unsigned int offset)
{
if (!pskb_may_pull(skb, hlen))
5392: e8 00 00 00 00 callq 5397 <vxlan_gro_receive+0x3b7>
5397: 48 85 c0 test %rax,%rax
539a: 48 8b 4d d0 mov -0x30(%rbp),%rcx
539e: 4c 8b 4d c8 mov -0x38(%rbp),%r9
53a2: 4c 8b 55 c0 mov -0x40(%rbp),%r10
53a6: 4c 8b 45 b8 mov -0x48(%rbp),%r8
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
53aa: 0f 85 2d fe ff ff jne 51dd <vxlan_gro_receive+0x1fd>
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
53b0: 80 8b 93 00 00 00 10 orb $0x10,0x93(%rbx)
53b7: ba 01 00 00 00 mov $0x1,%edx
53bc: 45 31 ff xor %r15d,%r15d
53bf: e9 89 fc ff ff jmpq 504d <vxlan_gro_receive+0x6d>
53c4: 66 90 xchg %ax,%ax
53c6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
53cd: 00 00 00
00000000000053d0 <vxlan_rcv>:
53d0: e8 00 00 00 00 callq 53d5 <vxlan_rcv+0x5>
53d5: 55 push %rbp
53d6: 48 89 e5 mov %rsp,%rbp
53d9: 41 57 push %r15
53db: 41 56 push %r14
53dd: 41 55 push %r13
53df: 41 54 push %r12
offset = start + vxlan_rco_offset(vni_field);
vh = skb_gro_remcsum_process(skb, (void *)vh, off, hdrlen,
start, offset, grc, nopartial);
skb->remcsum_offload = 1;
53e1: 49 89 f4 mov %rsi,%r12
53e4: 53 push %rbx
53e5: 48 89 fb mov %rdi,%rbx
53e8: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
static struct sk_buff **vxlan_gro_receive(struct sock *sk,
struct sk_buff **head,
struct sk_buff *skb)
{
struct sk_buff *p, **pp = NULL;
53ec: 48 83 ec 60 sub $0x60,%rsp
53f0: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
53f7: 00 00
53f9: 48 89 44 24 58 mov %rax,0x58(%rsp)
53fe: 31 c0 xor %eax,%eax
return err <= 1;
}
/* Callback from net/ipv4/udp.c to receive packets */
static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
{
5400: 8b 86 80 00 00 00 mov 0x80(%rsi),%eax
5406: 89 c2 mov %eax,%edx
5408: 2b 96 84 00 00 00 sub 0x84(%rsi),%edx
540e: 83 fa 0f cmp $0xf,%edx
5411: 0f 86 b9 02 00 00 jbe 56d0 <vxlan_rcv+0x300>
5417: 41 0f b7 84 24 c2 00 movzwl 0xc2(%r12),%eax
541e: 00 00
5420: 49 03 84 24 d0 00 00 add 0xd0(%r12),%rax
5427: 00
5428: 4c 8b 68 08 mov 0x8(%rax),%r13
542c: 44 8b 70 0c mov 0xc(%rax),%r14d
5430: 41 f6 c5 08 test $0x8,%r13b
5434: 44 89 e9 mov %r13d,%ecx
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
5437: 0f 84 80 00 00 00 je 54bd <vxlan_rcv+0xed>
543d: 4c 8b bb 48 02 00 00 mov 0x248(%rbx),%r15
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
5444: 4c 89 ee mov %r13,%rsi
return skb->transport_header != (typeof(skb->transport_header))~0U;
}
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
{
return skb->head + skb->transport_header;
5447: 48 83 e6 f7 and $0xfffffffffffffff7,%rsi
544b: 49 89 f5 mov %rsi,%r13
544e: 4d 85 ff test %r15,%r15
5451: 74 3d je 5490 <vxlan_rcv+0xc0>
5453: 41 8b bf 1c 20 00 00 mov 0x201c(%r15),%edi
/* Need UDP and VXLAN header to be present */
if (!pskb_may_pull(skb, VXLAN_HLEN))
goto drop;
unparsed = *vxlan_hdr(skb);
545a: f7 c7 00 20 00 00 test $0x2000,%edi
/* VNI flag always required to be set */
if (!(unparsed.vx_flags & VXLAN_HF_VNI)) {
5460: 0f 85 83 00 00 00 jne 54e9 <vxlan_rcv+0x119>
5466: 44 89 f0 mov %r14d,%eax
5469: c1 e0 08 shl $0x8,%eax
546c: 69 d0 47 86 c8 61 imul $0x61c88647,%eax,%edx
5472: c1 ea 16 shr $0x16,%edx
ntohl(vxlan_hdr(skb)->vx_flags),
ntohl(vxlan_hdr(skb)->vx_vni));
/* Return non vxlan pkt */
goto drop;
}
unparsed.vx_flags &= ~VXLAN_HF_VNI;
5475: 49 8d 54 d7 10 lea 0x10(%r15,%rdx,8),%rdx
547a: 48 8b 5a 08 mov 0x8(%rdx),%rbx
unparsed.vx_vni &= ~VXLAN_VNI_MASK;
vs = rcu_dereference_sk_user_data(sk);
if (!vs)
547e: 48 85 db test %rbx,%rbx
5481: 74 0d je 5490 <vxlan_rcv+0xc0>
static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
{
struct vxlan_dev *vxlan;
/* For flow based devices, map all packets to VNI 0 */
if (vs->flags & VXLAN_F_COLLECT_METADATA)
5483: 3b 43 60 cmp 0x60(%rbx),%eax
5486: 74 67 je 54ef <vxlan_rcv+0x11f>
5488: 48 8b 1b mov (%rbx),%rbx
548b: 48 85 db test %rbx,%rbx
548e: 75 f3 jne 5483 <vxlan_rcv+0xb3>
5490: 4c 89 e7 mov %r12,%rdi
5493: e8 00 00 00 00 callq 5498 <vxlan_rcv+0xc8>
static inline __be32 vxlan_vni(__be32 vni_field)
{
#if defined(__BIG_ENDIAN)
return (__force __be32)((__force u32)vni_field >> 8);
#else
return (__force __be32)((__force u32)(vni_field & VXLAN_VNI_MASK) << 8);
5498: 31 c0 xor %eax,%eax
549a: 48 8b 4c 24 58 mov 0x58(%rsp),%rcx
549f: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
54a6: 00 00
vni = 0;
hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
54a8: 0f 85 e7 08 00 00 jne 5d95 <vxlan_rcv+0x9c5>
54ae: 48 8d 65 d8 lea -0x28(%rbp),%rsp
54b2: 5b pop %rbx
if (vxlan->default_dst.remote_vni == vni)
54b3: 41 5c pop %r12
54b5: 41 5d pop %r13
54b7: 41 5e pop %r14
54b9: 41 5f pop %r15
/* For flow based devices, map all packets to VNI 0 */
if (vs->flags & VXLAN_F_COLLECT_METADATA)
vni = 0;
hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
54bb: 5d pop %rbp
54bc: c3 retq
54bd: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
gro_cells_receive(&vxlan->gro_cells, skb);
return 0;
drop:
/* Consume bad packet */
kfree_skb(skb);
54c2: eb cc jmp 5490 <vxlan_rcv+0xc0>
54c4: 8b 48 08 mov 0x8(%rax),%ecx
54c7: 49 8b 74 24 20 mov 0x20(%r12),%rsi
return 0;
}
54cc: 45 89 f0 mov %r14d,%r8d
54cf: 41 0f c8 bswap %r8d
54d2: 48 c7 c2 00 00 00 00 mov $0x0,%rdx
54d9: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
54e0: 0f c9 bswap %ecx
54e2: e8 00 00 00 00 callq 54e7 <vxlan_rcv+0x117>
54e7: eb a7 jmp 5490 <vxlan_rcv+0xc0>
54e9: 31 d2 xor %edx,%edx
54eb: 31 c0 xor %eax,%eax
54ed: eb 86 jmp 5475 <vxlan_rcv+0xa5>
54ef: 81 e7 00 40 00 00 and $0x4000,%edi
goto drop;
unparsed = *vxlan_hdr(skb);
/* VNI flag always required to be set */
if (!(unparsed.vx_flags & VXLAN_HF_VNI)) {
netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
54f5: 0f 85 74 01 00 00 jne 566f <vxlan_rcv+0x29f>
54fb: ba 65 58 00 00 mov $0x5865,%edx
5500: 31 c9 xor %ecx,%ecx
5502: c6 44 24 27 00 movb $0x0,0x27(%rsp)
5507: 48 8b 43 30 mov 0x30(%rbx),%rax
550b: 48 8b 7b 38 mov 0x38(%rbx),%rdi
550f: 45 31 c0 xor %r8d,%r8d
5512: be 10 00 00 00 mov $0x10,%esi
5517: 48 39 b8 80 04 00 00 cmp %rdi,0x480(%rax)
{
struct vxlan_dev *vxlan;
/* For flow based devices, map all packets to VNI 0 */
if (vs->flags & VXLAN_F_COLLECT_METADATA)
vni = 0;
551e: 4c 89 e7 mov %r12,%rdi
goto drop;
/* For backwards compatibility, only allow reserved fields to be
* used by VXLAN extensions if explicitly requested.
*/
if (vs->flags & VXLAN_F_GPE) {
5521: 41 0f 95 c0 setne %r8b
5525: e8 00 00 00 00 callq 552a <vxlan_rcv+0x15a>
552a: 85 c0 test %eax,%eax
552c: 0f 85 5e ff ff ff jne 5490 <vxlan_rcv+0xc0>
struct vxlan_sock *vs;
struct vxlanhdr unparsed;
struct vxlan_metadata _md;
struct vxlan_metadata *md = &_md;
__be16 protocol = htons(ETH_P_TEB);
bool raw_proto = false;
5532: 41 8b 97 1c 20 00 00 mov 0x201c(%r15),%edx
5539: f6 c6 20 test $0x20,%dh
if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags))
goto drop;
raw_proto = true;
}
if (__iptunnel_pull_header(skb, VXLAN_HLEN, protocol, raw_proto,
553c: 0f 85 b4 01 00 00 jne 56f6 <vxlan_rcv+0x326>
5542: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
5547: 4c 8d 44 24 2c lea 0x2c(%rsp),%r8
554c: c7 44 24 2c 00 00 00 movl $0x0,0x2c(%rsp)
5553: 00
5554: 44 89 f0 mov %r14d,%eax
5557: 44 89 e9 mov %r13d,%ecx
555a: 25 00 00 00 ff and $0xff000000,%eax
555f: f6 c6 04 test $0x4,%dh
5562: 89 c7 mov %eax,%edi
5564: 0f 85 e8 01 00 00 jne 5752 <vxlan_rcv+0x382>
/* salt for hash table */
static u32 vxlan_salt __read_mostly;
static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
{
return vs->flags & VXLAN_F_COLLECT_METADATA ||
556a: f6 c6 08 test $0x8,%dh
556d: 0f 85 25 03 00 00 jne 5898 <vxlan_rcv+0x4c8>
5573: 85 c9 test %ecx,%ecx
5575: 0f 85 15 ff ff ff jne 5490 <vxlan_rcv+0xc0>
struct pcpu_sw_netstats *stats;
struct vxlan_dev *vxlan;
struct vxlan_sock *vs;
struct vxlanhdr unparsed;
struct vxlan_metadata _md;
struct vxlan_metadata *md = &_md;
557b: 85 ff test %edi,%edi
md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
skb_dst_set(skb, (struct dst_entry *)tun_dst);
} else {
memset(md, 0, sizeof(*md));
557d: 0f 85 0d ff ff ff jne 5490 <vxlan_rcv+0xc0>
5583: 80 7c 24 27 00 cmpb $0x0,0x27(%rsp)
ntohl(vxlan_hdr(skb)->vx_vni));
/* Return non vxlan pkt */
goto drop;
}
unparsed.vx_flags &= ~VXLAN_HF_VNI;
unparsed.vx_vni &= ~VXLAN_VNI_MASK;
5588: 0f 84 85 03 00 00 je 5913 <vxlan_rcv+0x543>
558e: 49 8b 8c 24 d0 00 00 mov 0xd0(%r12),%rcx
5595: 00
skb_dst_set(skb, (struct dst_entry *)tun_dst);
} else {
memset(md, 0, sizeof(*md));
}
if (vs->flags & VXLAN_F_REMCSUM_RX)
5596: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
559d: 00
if (!vxlan_remcsum(&unparsed, skb, vs->flags))
goto drop;
if (vs->flags & VXLAN_F_GBP)
559e: 45 0f b7 ac 24 c4 00 movzwl 0xc4(%r12),%r13d
55a5: 00 00
vxlan_parse_gbp_hdr(&unparsed, skb, vs->flags, md);
/* Note that GBP and GPE can never be active together. This is
* ensured in vxlan_dev_configure.
*/
if (unparsed.vx_flags || unparsed.vx_vni) {
55a7: 48 29 c8 sub %rcx,%rax
55aa: 66 41 89 84 24 c6 00 mov %ax,0xc6(%r12)
55b1: 00 00
* adding extensions to VXLAN.
*/
goto drop;
}
if (!raw_proto) {
55b3: 48 8b 73 30 mov 0x30(%rbx),%rsi
55b7: 89 c2 mov %eax,%edx
55b9: 41 80 a4 24 90 00 00 andb $0xf8,0x90(%r12)
55c0: 00 f8
return skb->mac_header != (typeof(skb->mac_header))~0U;
}
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data - skb->head;
55c2: 49 89 74 24 20 mov %rsi,0x20(%r12)
55c7: 66 41 89 94 24 c4 00 mov %dx,0xc4(%r12)
55ce: 00 00
55d0: 49 01 cd add %rcx,%r13
55d3: 49 8b 57 10 mov 0x10(%r15),%rdx
55d7: 48 8b 52 20 mov 0x20(%rdx),%rdx
55db: 0f b7 72 10 movzwl 0x10(%rdx),%esi
55df: 66 83 fe 02 cmp $0x2,%si
if (!vxlan_set_mac(vxlan, vs, skb))
goto drop;
} else {
skb_reset_mac_header(skb);
skb->dev = vxlan->dev;
55e3: 0f 84 0b 04 00 00 je 59f4 <vxlan_rcv+0x624>
skb->pkt_type = PACKET_HOST;
55e9: 41 0f b7 bc 24 c0 00 movzwl 0xc0(%r12),%edi
55f0: 00 00
if (!raw_proto) {
if (!vxlan_set_mac(vxlan, vs, skb))
goto drop;
} else {
skb_reset_mac_header(skb);
skb->dev = vxlan->dev;
55f2: 66 83 ff 08 cmp $0x8,%di
55f6: 0f 84 84 05 00 00 je 5b80 <vxlan_rcv+0x7b0>
return skb->head + skb->network_header;
}
static inline void skb_reset_network_header(struct sk_buff *skb)
{
skb->network_header = skb->data - skb->head;
55fc: 66 81 ff 86 dd cmp $0xdd86,%di
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
5601: 0f 84 78 04 00 00 je 5a7f <vxlan_rcv+0x6af>
return vni_field;
}
static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
{
return vs->sock->sk->sk_family;
5607: 48 8b 43 30 mov 0x30(%rbx),%rax
560b: 48 8b 80 88 04 00 00 mov 0x488(%rax),%rax
static bool vxlan_ecn_decapsulate(struct vxlan_sock *vs, void *oiph,
struct sk_buff *skb)
{
int err = 0;
if (vxlan_get_sk_family(vs) == AF_INET)
5612: 65 48 03 05 00 00 00 add %gs:0x0(%rip),%rax # 561a <vxlan_rcv+0x24a>
5619: 00
static inline int IP6_ECN_decapsulate(const struct ipv6hdr *oipv6h,
struct sk_buff *skb)
{
__u8 inner;
if (skb->protocol == htons(ETH_P_IP))
561a: 48 83 00 01 addq $0x1,(%rax)
561e: 41 8b 94 24 80 00 00 mov 0x80(%r12),%edx
5625: 00
5626: 48 01 50 08 add %rdx,0x8(%rax)
562a: 48 8b 83 f0 00 00 00 mov 0xf0(%rbx),%rax
inner = ip_hdr(skb)->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
5631: 48 85 c0 test %rax,%rax
5634: 74 2c je 5662 <vxlan_rcv+0x292>
5636: 41 f6 84 24 8e 00 00 testb $0x1,0x8e(%r12)
563d: 00 01
++vxlan->dev->stats.rx_frame_errors;
++vxlan->dev->stats.rx_errors;
goto drop;
}
stats = this_cpu_ptr(vxlan->dev->tstats);
563f: 0f 84 72 05 00 00 je 5bb7 <vxlan_rcv+0x7e7>
5645: 41 8b 94 24 cc 00 00 mov 0xcc(%r12),%edx
564c: 00
u64_stats_update_begin(&stats->syncp);
stats->rx_packets++;
564d: 49 03 94 24 d0 00 00 add 0xd0(%r12),%rdx
5654: 00
stats->rx_bytes += skb->len;
5655: 8b 52 20 mov 0x20(%rdx),%edx
5658: 66 83 fa 01 cmp $0x1,%dx
static inline int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
{
struct gro_cell *cell;
struct net_device *dev = skb->dev;
if (!gcells->cells || skb_cloned(skb) || !(dev->features & NETIF_F_GRO))
565c: 0f 84 55 05 00 00 je 5bb7 <vxlan_rcv+0x7e7>
5662: 4c 89 e7 mov %r12,%rdi
5665: e8 00 00 00 00 callq 566a <vxlan_rcv+0x29a>
* one of multiple shared copies of the buffer. Cloned buffers are
* shared data so must not be written to under normal circumstances.
*/
static inline int skb_cloned(const struct sk_buff *skb)
{
return skb->cloned &&
566a: e9 29 fe ff ff jmpq 5498 <vxlan_rcv+0xc8>
566f: 40 f6 c6 04 test $0x4,%sil
5673: 0f 84 17 fe ff ff je 5490 <vxlan_rcv+0xc0>
};
#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
return skb->head + skb->end;
5679: 40 f6 c6 31 test $0x31,%sil
567d: 0f 85 0d fe ff ff jne 5490 <vxlan_rcv+0xc0>
5683: 48 89 f0 mov %rsi,%rax
5686: 48 c1 e8 18 shr $0x18,%rax
* one of multiple shared copies of the buffer. Cloned buffers are
* shared data so must not be written to under normal circumstances.
*/
static inline int skb_cloned(const struct sk_buff *skb)
{
return skb->cloned &&
568a: 3c 02 cmp $0x2,%al
568c: 0f 84 77 02 00 00 je 5909 <vxlan_rcv+0x539>
return netif_rx(skb);
5692: 3c 03 cmp $0x3,%al
5694: 0f 84 65 02 00 00 je 58ff <vxlan_rcv+0x52f>
569a: 3c 01 cmp $0x1,%al
569c: ba 08 00 00 00 mov $0x8,%edx
struct sk_buff *skb, u32 vxflags)
{
struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed;
/* Need to have Next Protocol set for interfaces in GPE mode. */
if (!gpe->np_applied)
56a1: 0f 85 e9 fd ff ff jne 5490 <vxlan_rcv+0xc0>
56a7: 41 89 cd mov %ecx,%r13d
return false;
/* "When the O bit is set to 1, the packet is an OAM packet and OAM
* processing MUST occur." However, we don't implement OAM
* processing, thus drop the packet.
*/
if (gpe->oam_flag)
56aa: 48 b8 00 00 00 00 ff movabs $0xffffffff00000000,%rax
56b1: ff ff ff
return false;
switch (gpe->next_protocol) {
56b4: b9 01 00 00 00 mov $0x1,%ecx
56b9: 41 81 e5 c2 ff ff 00 and $0xffffc2,%r13d
56c0: 48 21 c6 and %rax,%rsi
56c3: c6 44 24 27 01 movb $0x1,0x27(%rsp)
56c8: 49 09 f5 or %rsi,%r13
56cb: e9 37 fe ff ff jmpq 5507 <vxlan_rcv+0x137>
56d0: 83 f8 0f cmp $0xf,%eax
56d3: 0f 86 b7 fd ff ff jbe 5490 <vxlan_rcv+0xc0>
break;
default:
return false;
}
unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS;
56d9: be 10 00 00 00 mov $0x10,%esi
56de: 4c 89 e7 mov %r12,%rdi
56e1: 29 d6 sub %edx,%esi
56e3: e8 00 00 00 00 callq 56e8 <vxlan_rcv+0x318>
56e8: 48 85 c0 test %rax,%rax
56eb: 0f 84 9f fd ff ff je 5490 <vxlan_rcv+0xc0>
56f1: e9 21 fd ff ff jmpq 5417 <vxlan_rcv+0x47>
* used by VXLAN extensions if explicitly requested.
*/
if (vs->flags & VXLAN_F_GPE) {
if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags))
goto drop;
raw_proto = true;
56f6: 41 0f b7 84 24 c2 00 movzwl 0xc2(%r12),%eax
56fd: 00 00
break;
default:
return false;
}
unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS;
56ff: 49 8b 94 24 d0 00 00 mov 0xd0(%r12),%rdx
5706: 00
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
5707: 41 b8 04 00 00 00 mov $0x4,%r8d
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
570d: 4c 89 e7 mov %r12,%rdi
5710: 8b 4c 02 0c mov 0xc(%rdx,%rax,1),%ecx
5714: 49 8b 47 10 mov 0x10(%r15),%rax
__be16 protocol = htons(ETH_P_TEB);
bool raw_proto = false;
void *oiph;
/* Need UDP and VXLAN header to be present */
if (!pskb_may_pull(skb, VXLAN_HLEN))
5718: ba 00 04 00 00 mov $0x400,%edx
571d: 48 8b 40 20 mov 0x20(%rax),%rax
5721: c1 e1 08 shl $0x8,%ecx
5724: 48 c1 e1 20 shl $0x20,%rcx
if (__iptunnel_pull_header(skb, VXLAN_HLEN, protocol, raw_proto,
!net_eq(vxlan->net, dev_net(vxlan->dev))))
goto drop;
if (vxlan_collect_metadata(vs)) {
__be32 vni = vxlan_vni(vxlan_hdr(skb)->vx_vni);
5728: 0f b7 70 10 movzwl 0x10(%rax),%esi
572c: e8 00 00 00 00 callq 5731 <vxlan_rcv+0x361>
5731: 48 85 c0 test %rax,%rax
5734: 0f 84 56 fd ff ff je 5490 <vxlan_rcv+0xc0>
struct metadata_dst *tun_dst;
tun_dst = udp_tun_rx_dst(skb, vxlan_get_sk_family(vs), TUNNEL_KEY,
573a: 49 89 44 24 58 mov %rax,0x58(%r12)
573f: 4c 8d 80 f0 00 00 00 lea 0xf0(%rax),%r8
5746: 41 8b 97 1c 20 00 00 mov 0x201c(%r15),%edx
574d: e9 02 fe ff ff jmpq 5554 <vxlan_rcv+0x184>
5752: 41 f7 c5 00 20 00 00 test $0x2000,%r13d
5759: 45 89 e9 mov %r13d,%r9d
575c: 0f 84 17 01 00 00 je 5879 <vxlan_rcv+0x4a9>
vxlan_vni_to_tun_id(vni), sizeof(*md));
if (!tun_dst)
5762: 41 f6 84 24 93 00 00 testb $0x10,0x93(%r12)
5769: 00 10
* Sets skb dst, assuming a reference was taken on dst and should
* be released by skb_dst_drop()
*/
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
{
skb->_skb_refdst = (unsigned long)dst;
576b: 0f 85 08 01 00 00 jne 5879 <vxlan_rcv+0x4a9>
}
}
static inline void *ip_tunnel_info_opts(struct ip_tunnel_info *info)
{
return info + 1;
5771: 41 81 e6 00 00 00 7f and $0x7f000000,%r14d
5778: 48 98 cltq
577a: 41 8b bc 24 80 00 00 mov 0x80(%r12),%edi
5781: 00
static bool vxlan_remcsum(struct vxlanhdr *unparsed,
struct sk_buff *skb, u32 vxflags)
{
size_t start, offset;
if (!(unparsed->vx_flags & VXLAN_HF_RCO) || skb->remcsum_offload)
5782: 41 0f ce bswap %r14d
5785: 48 c1 f8 3f sar $0x3f,%rax
5789: 43 8d 34 36 lea (%r14,%r14,1),%esi
578d: 48 83 e0 f6 and $0xfffffffffffffff6,%rax
5791: 48 8d 44 06 10 lea 0x10(%rsi,%rax,1),%rax
5796: 49 89 f6 mov %rsi,%r14
5799: 89 fe mov %edi,%esi
579b: 41 2b b4 24 84 00 00 sub 0x84(%r12),%esi
57a2: 00
#endif
}
static inline size_t vxlan_rco_start(__be32 vni_field)
{
return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
57a3: 48 89 44 24 18 mov %rax,0x18(%rsp)
}
static inline size_t vxlan_rco_offset(__be32 vni_field)
{
return (vni_field & VXLAN_RCO_UDP) ?
offsetof(struct udphdr, check) :
57a8: 83 c0 02 add $0x2,%eax
57ab: 39 f0 cmp %esi,%eax
57ad: 0f 87 65 05 00 00 ja 5d18 <vxlan_rcv+0x948>
#endif
}
static inline size_t vxlan_rco_start(__be32 vni_field)
{
return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
57b3: 41 0f b7 84 24 c2 00 movzwl 0xc2(%r12),%eax
57ba: 00 00
57bc: 49 8b b4 24 d0 00 00 mov 0xd0(%r12),%rsi
57c3: 00
goto out;
start = vxlan_rco_start(unparsed->vx_vni);
offset = start + vxlan_rco_offset(unparsed->vx_vni);
57c4: 80 e6 10 and $0x10,%dh
57c7: 4c 8d 54 06 10 lea 0x10(%rsi,%rax,1),%r10
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
57cc: 0f 84 09 05 00 00 je 5cdb <vxlan_rcv+0x90b>
57d2: 41 0f b6 84 24 91 00 movzbl 0x91(%r12),%eax
57d9: 00 00
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
57db: 83 e0 06 and $0x6,%eax
57de: 3c 04 cmp $0x4,%al
57e0: 0f 85 58 06 00 00 jne 5e3e <vxlan_rcv+0xa6e>
if (!pskb_may_pull(skb, offset + sizeof(u16)))
return false;
skb_remcsum_process(skb, (void *)(vxlan_hdr(skb) + 1), start, offset,
57e6: 45 8b 9c 24 98 00 00 mov 0x98(%r12),%r11d
57ed: 00
57ee: 48 63 44 24 18 movslq 0x18(%rsp),%rax
57f3: 31 d2 xor %edx,%edx
static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
int start, int offset, bool nopartial)
{
__wsum delta;
if (!nopartial) {
57f5: 44 89 f6 mov %r14d,%esi
57f8: 4c 89 d7 mov %r10,%rdi
57fb: 44 89 5c 24 08 mov %r11d,0x8(%rsp)
5800: 44 89 4c 24 20 mov %r9d,0x20(%rsp)
skb_remcsum_adjust_partial(skb, ptr, start, offset);
return;
}
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
5805: 4c 89 44 24 10 mov %r8,0x10(%rsp)
580a: 49 8d 0c 02 lea (%r10,%rax,1),%rcx
580e: 48 89 4c 24 18 mov %rcx,0x18(%rsp)
5813: e8 00 00 00 00 callq 5818 <vxlan_rcv+0x448>
5818: 48 8b 4c 24 18 mov 0x18(%rsp),%rcx
581d: f7 d0 not %eax
581f: 44 8b 5c 24 08 mov 0x8(%rsp),%r11d
__wsum delta;
/* Subtract out checksum up to start */
csum = csum_sub(csum, csum_partial(ptr, start, 0));
5824: 41 01 c3 add %eax,%r11d
5827: 41 83 d3 00 adc $0x0,%r11d
582b: 44 89 da mov %r11d,%edx
582e: 66 45 31 db xor %r11w,%r11w
5832: 44 8b 4c 24 20 mov 0x20(%rsp),%r9d
5837: 0f b7 31 movzwl (%rcx),%esi
}
static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
int start, int offset)
{
__sum16 *psum = (__sum16 *)(ptr + offset);
583a: c1 e2 10 shl $0x10,%edx
583d: 44 89 d8 mov %r11d,%eax
5840: 01 d0 add %edx,%eax
5842: 15 ff ff 00 00 adc $0xffff,%eax
__wsum delta;
/* Subtract out checksum up to start */
csum = csum_sub(csum, csum_partial(ptr, start, 0));
5847: f7 d0 not %eax
5849: 4c 8b 44 24 10 mov 0x10(%rsp),%r8
584e: c1 e8 10 shr $0x10,%eax
5851: 66 89 01 mov %ax,(%rcx)
5854: 89 c2 mov %eax,%edx
5856: f7 d6 not %esi
5858: 41 8b 84 24 98 00 00 mov 0x98(%r12),%eax
585f: 00
{
asm(" addl %1,%0\n"
" adcl $0xffff,%0"
: "=r" (sum)
: "r" ((__force u32)sum << 16),
"0" ((__force u32)sum & 0xffff0000));
5860: 01 f2 add %esi,%edx
5862: 83 d2 00 adc $0x0,%edx
5865: 01 d0 add %edx,%eax
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
asm("addl %2,%0\n\t"
5867: 83 d0 00 adc $0x0,%eax
static inline __sum16 csum_fold(__wsum sum)
{
asm(" addl %1,%0\n"
" adcl $0xffff,%0"
: "=r" (sum)
: "r" ((__force u32)sum << 16),
586a: 41 89 84 24 98 00 00 mov %eax,0x98(%r12)
5871: 00
* the last step before putting a checksum into a packet.
* Make sure not to mix with 64bit checksums.
*/
static inline __sum16 csum_fold(__wsum sum)
{
asm(" addl %1,%0\n"
5872: 41 8b 97 1c 20 00 00 mov 0x201c(%r15),%edx
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
asm("addl %2,%0\n\t"
5879: 44 89 c9 mov %r9d,%ecx
587c: 48 b8 00 00 00 00 ff movabs $0xffffffff00000000,%rax
5883: ff ff ff
5886: 31 ff xor %edi,%edi
5888: 80 e5 df and $0xdf,%ch
588b: 49 21 c5 and %rax,%r13
588e: 89 ce mov %ecx,%esi
5890: 49 09 f5 or %rsi,%r13
5893: e9 d2 fc ff ff jmpq 556a <vxlan_rcv+0x19a>
5898: f6 c1 80 test $0x80,%cl
}
delta = remcsum_adjust(ptr, skb->csum, start, offset);
/* Adjust skb->csum since we changed the packet */
skb->csum = csum_add(skb->csum, delta);
589b: 74 5a je 58f7 <vxlan_rcv+0x527>
589d: 4c 89 ee mov %r13,%rsi
58a0: 48 c1 ee 10 shr $0x10,%rsi
58a4: 66 c1 c6 08 rol $0x8,%si
58a8: 0f b7 f6 movzwl %si,%esi
!!(vxflags & VXLAN_F_REMCSUM_NOPARTIAL));
out:
unparsed->vx_flags &= ~VXLAN_HF_RCO;
58ab: 41 89 30 mov %esi,(%r8)
58ae: 49 8b 74 24 58 mov 0x58(%r12),%rsi
58b3: 48 83 e6 fe and $0xfffffffffffffffe,%rsi
unparsed->vx_vni &= VXLAN_VNI_MASK;
58b7: 74 0f je 58c8 <vxlan_rcv+0x4f8>
return false;
skb_remcsum_process(skb, (void *)(vxlan_hdr(skb) + 1), start, offset,
!!(vxflags & VXLAN_F_REMCSUM_NOPARTIAL));
out:
unparsed->vx_flags &= ~VXLAN_HF_RCO;
58b9: 66 83 8e c8 00 00 00 orw $0x10,0xc8(%rsi)
58c0: 10
58c1: c6 86 e8 00 00 00 04 movb $0x4,0xe8(%rsi)
struct vxlan_metadata *md)
{
struct vxlanhdr_gbp *gbp = (struct vxlanhdr_gbp *)unparsed;
struct metadata_dst *tun_dst;
if (!(unparsed->vx_flags & VXLAN_HF_GBP))
58c8: 44 89 e8 mov %r13d,%eax
58cb: 0f b6 f4 movzbl %ah,%esi
goto out;
md->gbp = ntohs(gbp->policy_id);
58ce: 40 f6 c6 40 test $0x40,%sil
58d2: 74 07 je 58db <vxlan_rcv+0x50b>
58d4: 41 81 08 00 00 40 00 orl $0x400000,(%r8)
58db: 83 e6 08 and $0x8,%esi
tun_dst = (struct metadata_dst *)skb_dst(skb);
if (tun_dst) {
58de: 74 07 je 58e7 <vxlan_rcv+0x517>
58e0: 41 81 08 00 00 08 00 orl $0x80000,(%r8)
58e7: 80 e6 20 and $0x20,%dh
tun_dst->u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT;
58ea: 75 0b jne 58f7 <vxlan_rcv+0x527>
58ec: 41 8b 10 mov (%r8),%edx
58ef: 41 89 94 24 b4 00 00 mov %edx,0xb4(%r12)
58f6: 00
tun_dst->u.tun_info.options_len = sizeof(*md);
58f7: 83 e1 7f and $0x7f,%ecx
}
if (gbp->dont_learn)
58fa: e9 74 fc ff ff jmpq 5573 <vxlan_rcv+0x1a3>
58ff: ba 65 58 00 00 mov $0x5865,%edx
md->gbp |= VXLAN_GBP_DONT_LEARN;
5904: e9 9e fd ff ff jmpq 56a7 <vxlan_rcv+0x2d7>
5909: ba 86 dd 00 00 mov $0xdd86,%edx
if (gbp->policy_applied)
590e: e9 94 fd ff ff jmpq 56a7 <vxlan_rcv+0x2d7>
md->gbp |= VXLAN_GBP_POLICY_APPLIED;
5913: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
591a: 00
/* In flow-based mode, GBP is carried in dst_metadata */
if (!(vxflags & VXLAN_F_COLLECT_METADATA))
591b: 49 2b 84 24 d0 00 00 sub 0xd0(%r12),%rax
5922: 00
skb->mark = md->gbp;
5923: 4c 89 e7 mov %r12,%rdi
5926: 66 41 89 84 24 c6 00 mov %ax,0xc6(%r12)
592d: 00 00
out:
unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS;
592f: 48 8b 73 30 mov 0x30(%rbx),%rsi
5933: e8 00 00 00 00 callq 5938 <vxlan_rcv+0x568>
5938: 66 41 89 84 24 c0 00 mov %ax,0xc0(%r12)
593f: 00 00
* processing, thus drop the packet.
*/
if (gpe->oam_flag)
return false;
switch (gpe->next_protocol) {
5941: 41 0f b6 84 24 91 00 movzbl 0x91(%r12),%eax
5948: 00 00
return skb->mac_header != (typeof(skb->mac_header))~0U;
}
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data - skb->head;
594a: 41 0f b7 b4 24 c6 00 movzwl 0xc6(%r12),%esi
5951: 00 00
struct sk_buff *skb)
{
union vxlan_addr saddr;
skb_reset_mac_header(skb);
skb->protocol = eth_type_trans(skb, vxlan->dev);
5953: 49 8b 8c 24 d0 00 00 mov 0xd0(%r12),%rcx
595a: 00
595b: 89 c2 mov %eax,%edx
595d: 83 e2 06 and $0x6,%edx
5960: 48 8d 3c 31 lea (%rcx,%rsi,1),%rdi
5964: 80 fa 04 cmp $0x4,%dl
5967: 0f 84 e9 03 00 00 je 5d56 <vxlan_rcv+0x986>
596d: 80 fa 06 cmp $0x6,%dl
5970: 0f 84 18 02 00 00 je 5b8e <vxlan_rcv+0x7be>
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
5976: 48 8b 43 30 mov 0x30(%rbx),%rax
skb->network_header += offset;
}
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
return skb->head + skb->mac_header;
597a: 8b 57 06 mov 0x6(%rdi),%edx
597d: 4c 8b 80 38 03 00 00 mov 0x338(%rax),%r8
5984: 0f b7 47 0a movzwl 0xa(%rdi),%eax
5988: 66 41 33 40 04 xor 0x4(%r8),%ax
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
598d: 41 33 10 xor (%r8),%edx
skb->network_header += offset;
}
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
return skb->head + skb->mac_header;
5990: 0f b7 c0 movzwl %ax,%eax
5993: 09 c2 or %eax,%edx
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
5995: 0f 84 f5 fa ff ff je 5490 <vxlan_rcv+0xc0>
599b: 49 8b 47 10 mov 0x10(%r15),%rax
skb->csum = csum_block_sub(skb->csum,
csum_partial(start, len, 0), off);
else if (skb->ip_summed == CHECKSUM_PARTIAL &&
599f: 45 0f b7 ac 24 c4 00 movzwl 0xc4(%r12),%r13d
59a6: 00 00
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
/* Ignore packet loops (and multicast echo) */
if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
59a8: 48 8b 40 20 mov 0x20(%rax),%rax
59ac: 66 83 78 10 02 cmpw $0x2,0x10(%rax)
59b1: 0f 84 ff 02 00 00 je 5cb6 <vxlan_rcv+0x8e6>
59b7: 4a 8b 44 29 08 mov 0x8(%rcx,%r13,1),%rax
59bc: 4a 8b 54 29 10 mov 0x10(%rcx,%r13,1),%rdx
59c1: 48 89 44 24 38 mov %rax,0x38(%rsp)
59c6: b8 0a 00 00 00 mov $0xa,%eax
return vni_field;
}
static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
{
return vs->sock->sk->sk_family;
59cb: 48 89 54 24 40 mov %rdx,0x40(%rsp)
return false;
/* Get address from the outer IP header */
if (vxlan_get_sk_family(vs) == AF_INET) {
saddr.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
59d0: 66 89 44 24 30 mov %ax,0x30(%rsp)
59d5: f6 83 98 00 00 00 01 testb $0x1,0x98(%rbx)
/* Ignore packet loops (and multicast echo) */
if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
return false;
/* Get address from the outer IP header */
if (vxlan_get_sk_family(vs) == AF_INET) {
59dc: 0f 85 a2 02 00 00 jne 5c84 <vxlan_rcv+0x8b4>
59e2: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
59e9: 00
saddr.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
saddr.sa.sa_family = AF_INET;
#if IS_ENABLED(CONFIG_IPV6)
} else {
saddr.sin6.sin6_addr = ipv6_hdr(skb)->saddr;
59ea: 48 29 c8 sub %rcx,%rax
59ed: 89 c2 mov %eax,%edx
59ef: e9 d3 fb ff ff jmpq 55c7 <vxlan_rcv+0x1f7>
59f4: 45 0f b7 84 24 c0 00 movzwl 0xc0(%r12),%r8d
59fb: 00 00
59fd: 66 41 83 f8 08 cmp $0x8,%r8w
saddr.sa.sa_family = AF_INET6;
5a02: 0f 84 c6 02 00 00 je 5cce <vxlan_rcv+0x8fe>
#endif
}
if ((vxlan->flags & VXLAN_F_LEARN) &&
5a08: 66 41 81 f8 86 dd cmp $0xdd86,%r8w
5a0e: 0f 85 f3 fb ff ff jne 5607 <vxlan_rcv+0x237>
5a14: 0f b7 c0 movzwl %ax,%eax
5a17: 0f b7 3c 01 movzwl (%rcx,%rax,1),%edi
5a1b: 66 c1 c7 08 rol $0x8,%di
5a1f: 66 c1 ef 04 shr $0x4,%di
5a23: 83 e7 03 and $0x3,%edi
static inline int IP_ECN_decapsulate(const struct iphdr *oiph,
struct sk_buff *skb)
{
__u8 inner;
if (skb->protocol == htons(ETH_P_IP))
5a26: 41 0f b6 55 01 movzbl 0x1(%r13),%edx
5a2b: 0f 85 2b 02 00 00 jne 5c5c <vxlan_rcv+0x88c>
5a31: 83 e2 03 and $0x3,%edx
5a34: 0f 84 cd fb ff ff je 5607 <vxlan_rcv+0x237>
inner = ip_hdr(skb)->tos;
else if (skb->protocol == htons(ETH_P_IPV6))
5a3a: 80 fa 02 cmp $0x2,%dl
5a3d: 0f 86 ea 01 00 00 jbe 5c2d <vxlan_rcv+0x85d>
5a43: 80 fa 03 cmp $0x3,%dl
5a46: 0f 85 bb fb ff ff jne 5607 <vxlan_rcv+0x237>
5a4c: 80 3d 00 00 00 00 00 cmpb $0x0,0x0(%rip) # 5a53 <vxlan_rcv+0x683>
* 2 if packet should be dropped
*/
static inline int INET_ECN_decapsulate(struct sk_buff *skb,
__u8 outer, __u8 inner)
{
if (INET_ECN_is_not_ect(inner)) {
5a53: 74 0d je 5a62 <vxlan_rcv+0x692>
5a55: e8 00 00 00 00 callq 5a5a <vxlan_rcv+0x68a>
else if (skb->protocol == htons(ETH_P_IPV6))
inner = ipv6_get_dsfield(ipv6_hdr(skb));
else
return 0;
return INET_ECN_decapsulate(skb, oiph->tos, inner);
5a5a: 85 c0 test %eax,%eax
* 2 if packet should be dropped
*/
static inline int INET_ECN_decapsulate(struct sk_buff *skb,
__u8 outer, __u8 inner)
{
if (INET_ECN_is_not_ect(inner)) {
5a5c: 0f 85 55 04 00 00 jne 5eb7 <vxlan_rcv+0xae7>
switch (outer & INET_ECN_MASK) {
5a62: 48 8b 43 30 mov 0x30(%rbx),%rax
5a66: 48 83 80 98 01 00 00 addq $0x1,0x198(%rax)
5a6d: 01
5a6e: 48 8b 43 30 mov 0x30(%rbx),%rax
5a72: 48 83 80 50 01 00 00 addq $0x1,0x150(%rax)
5a79: 01
5a7a: e9 11 fa ff ff jmpq 5490 <vxlan_rcv+0xc0>
#if IS_ENABLED(CONFIG_IPV6)
else
err = IP6_ECN_decapsulate(oiph, skb);
#endif
if (unlikely(err) && log_ecn_error) {
5a7f: 0f b7 c0 movzwl %ax,%eax
5a82: 44 0f b7 04 01 movzwl (%rcx,%rax,1),%r8d
if (vxlan_get_sk_family(vs) == AF_INET)
net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
5a87: 66 41 c1 c0 08 rol $0x8,%r8w
5a8c: 66 41 c1 e8 04 shr $0x4,%r8w
5a91: 41 0f b7 55 00 movzwl 0x0(%r13),%edx
oiph = skb_network_header(skb);
skb_reset_network_header(skb);
if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
++vxlan->dev->stats.rx_frame_errors;
5a96: 66 c1 c2 08 rol $0x8,%dx
5a9a: 66 c1 ea 04 shr $0x4,%dx
++vxlan->dev->stats.rx_errors;
5a9e: 41 83 e0 03 and $0x3,%r8d
5aa2: 75 52 jne 5af6 <vxlan_rcv+0x726>
5aa4: 83 e2 03 and $0x3,%edx
5aa7: 0f 84 5a fb ff ff je 5607 <vxlan_rcv+0x237>
goto drop;
5aad: 80 fa 02 cmp $0x2,%dl
5ab0: 0f 86 77 01 00 00 jbe 5c2d <vxlan_rcv+0x85d>
5ab6: 80 fa 03 cmp $0x3,%dl
5ab9: 0f 85 48 fb ff ff jne 5607 <vxlan_rcv+0x237>
5abf: 80 3d 00 00 00 00 00 cmpb $0x0,0x0(%rip) # 5ac6 <vxlan_rcv+0x6f6>
5ac6: 74 9a je 5a62 <vxlan_rcv+0x692>
5ac8: e8 00 00 00 00 callq 5acd <vxlan_rcv+0x6fd>
5acd: 85 c0 test %eax,%eax
* 2 if packet should be dropped
*/
static inline int INET_ECN_decapsulate(struct sk_buff *skb,
__u8 outer, __u8 inner)
{
if (INET_ECN_is_not_ect(inner)) {
5acf: 74 91 je 5a62 <vxlan_rcv+0x692>
5ad1: 41 be 02 00 00 00 mov $0x2,%r14d
switch (outer & INET_ECN_MASK) {
5ad7: 49 8d 75 08 lea 0x8(%r13),%rsi
5adb: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
5ae2: e8 00 00 00 00 callq 5ae7 <vxlan_rcv+0x717>
5ae7: 41 83 fe 02 cmp $0x2,%r14d
5aeb: 0f 84 71 ff ff ff je 5a62 <vxlan_rcv+0x692>
#if IS_ENABLED(CONFIG_IPV6)
else
err = IP6_ECN_decapsulate(oiph, skb);
#endif
if (unlikely(err) && log_ecn_error) {
5af1: e9 11 fb ff ff jmpq 5607 <vxlan_rcv+0x237>
5af6: 83 e2 03 and $0x3,%edx
if (vxlan_get_sk_family(vs) == AF_INET)
net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
&((struct iphdr *)oiph)->saddr,
((struct iphdr *)oiph)->tos);
else
net_info_ratelimited("non-ECT from %pI6\n",
5af9: 80 fa 03 cmp $0x3,%dl
5afc: 0f 85 05 fb ff ff jne 5607 <vxlan_rcv+0x237>
return 0;
case INET_ECN_ECT_0:
case INET_ECN_ECT_1:
return 1;
case INET_ECN_CE:
return 2;
5b02: 66 83 ff 08 cmp $0x8,%di
5b06: 0f 84 8e 02 00 00 je 5d9a <vxlan_rcv+0x9ca>
5b0c: 66 81 ff 86 dd cmp $0xdd86,%di
5b11: 0f 85 f0 fa ff ff jne 5607 <vxlan_rcv+0x237>
}
oiph = skb_network_header(skb);
skb_reset_network_header(skb);
if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
5b17: 41 8b 94 24 c8 00 00 mov 0xc8(%r12),%edx
5b1e: 00
5b1f: 48 01 c8 add %rcx,%rax
5b22: 48 8d 70 28 lea 0x28(%rax),%rsi
}
}
if (INET_ECN_is_ce(outer))
5b26: 48 01 d1 add %rdx,%rcx
5b29: 48 39 ce cmp %rcx,%rsi
5b2c: 0f 87 d5 fa ff ff ja 5607 <vxlan_rcv+0x237>
ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
}
static inline int INET_ECN_set_ce(struct sk_buff *skb)
{
switch (skb->protocol) {
5b32: 0f b7 10 movzwl (%rax),%edx
5b35: 66 c1 c2 08 rol $0x8,%dx
5b39: 80 e2 30 and $0x30,%dl
5b3c: 0f 84 c5 fa ff ff je 5607 <vxlan_rcv+0x237>
5b42: 8b 10 mov (%rax),%edx
5b44: 89 d1 mov %edx,%ecx
5b46: 80 cd 30 or $0x30,%ch
skb_tail_pointer(skb))
return IP_ECN_set_ce(ip_hdr(skb));
break;
case cpu_to_be16(ETH_P_IPV6):
if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
5b49: 89 08 mov %ecx,(%rax)
5b4b: 41 0f b6 84 24 91 00 movzbl 0x91(%r12),%eax
5b52: 00 00
5b54: 83 e0 06 and $0x6,%eax
5b57: 3c 04 cmp $0x4,%al
5b59: 0f 85 a8 fa ff ff jne 5607 <vxlan_rcv+0x237>
5b5f: 41 8b 84 24 98 00 00 mov 0x98(%r12),%eax
5b66: 00
5b67: f7 d2 not %edx
*/
static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph)
{
__be32 from, to;
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
5b69: 01 d0 add %edx,%eax
5b6b: 83 d0 00 adc $0x0,%eax
5b6e: 01 c8 add %ecx,%eax
5b70: 83 d0 00 adc $0x0,%eax
return 0;
from = *(__be32 *)iph;
5b73: 41 89 84 24 98 00 00 mov %eax,0x98(%r12)
5b7a: 00
to = from | htonl(INET_ECN_CE << 20);
*(__be32 *)iph = to;
if (skb->ip_summed == CHECKSUM_COMPLETE)
5b7b: e9 87 fa ff ff jmpq 5607 <vxlan_rcv+0x237>
5b80: 0f b7 c0 movzwl %ax,%eax
5b83: 44 0f b6 44 01 01 movzbl 0x1(%rcx,%rax,1),%r8d
5b89: e9 03 ff ff ff jmpq 5a91 <vxlan_rcv+0x6c1>
5b8e: 41 0f b7 94 24 98 00 movzwl 0x98(%r12),%edx
5b95: 00 00
5b97: 41 2b 94 24 d8 00 00 sub 0xd8(%r12),%edx
5b9e: 00
5b9f: 01 ca add %ecx,%edx
5ba1: 0f 89 cf fd ff ff jns 5976 <vxlan_rcv+0x5a6>
skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from),
5ba7: 83 e0 f9 and $0xfffffff9,%eax
5baa: 41 88 84 24 91 00 00 mov %al,0x91(%r12)
5bb1: 00
struct sk_buff *skb)
{
__u8 inner;
if (skb->protocol == htons(ETH_P_IP))
inner = ip_hdr(skb)->tos;
5bb2: e9 bf fd ff ff jmpq 5976 <vxlan_rcv+0x5a6>
5bb7: 49 8b 54 24 20 mov 0x20(%r12),%rdx
5bbc: f6 82 f1 00 00 00 40 testb $0x40,0xf1(%rdx)
5bc3: 0f 84 99 fa ff ff je 5662 <vxlan_rcv+0x292>
5bc9: 65 48 03 05 00 00 00 add %gs:0x0(%rip),%rax # 5bd1 <vxlan_rcv+0x801>
5bd0: 00
5bd1: 8b 3d 00 00 00 00 mov 0x0(%rip),%edi # 5bd7 <vxlan_rcv+0x807>
skb_checksum_start_offset(skb) < 0)
skb->ip_summed = CHECKSUM_NONE;
5bd7: 39 78 10 cmp %edi,0x10(%rax)
5bda: 0f 87 49 02 00 00 ja 5e29 <vxlan_rcv+0xa59>
5be0: 48 8b 50 08 mov 0x8(%rax),%rdx
5be4: 49 89 04 24 mov %rax,(%r12)
};
static inline int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
{
struct gro_cell *cell;
struct net_device *dev = skb->dev;
5be8: 49 89 54 24 08 mov %rdx,0x8(%r12)
if (!gcells->cells || skb_cloned(skb) || !(dev->features & NETIF_F_GRO))
5bed: 4c 89 22 mov %r12,(%rdx)
5bf0: 8b 78 10 mov 0x10(%rax),%edi
5bf3: 4c 89 60 08 mov %r12,0x8(%rax)
5bf7: 8d 57 01 lea 0x1(%rdi),%edx
return netif_rx(skb);
cell = this_cpu_ptr(gcells->cells);
5bfa: 83 fa 01 cmp $0x1,%edx
5bfd: 89 50 10 mov %edx,0x10(%rax)
5c00: 0f 85 92 f8 ff ff jne 5498 <vxlan_rcv+0xc8>
if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) {
5c06: 48 8b 50 28 mov 0x28(%rax),%rdx
5c0a: 48 8d 78 18 lea 0x18(%rax),%rdi
5c0e: 80 e2 02 and $0x2,%dl
static inline void __skb_queue_before(struct sk_buff_head *list,
struct sk_buff *next,
struct sk_buff *newsk)
{
__skb_insert(newsk, next->prev, next, list);
5c11: 0f 85 81 f8 ff ff jne 5498 <vxlan_rcv+0xc8>
struct sk_buff_head *list);
static inline void __skb_insert(struct sk_buff *newsk,
struct sk_buff *prev, struct sk_buff *next,
struct sk_buff_head *list)
{
newsk->next = next;
5c17: f0 0f ba 68 28 00 lock btsl $0x0,0x28(%rax)
newsk->prev = prev;
next->prev = prev->next = newsk;
5c1d: 0f 82 75 f8 ff ff jb 5498 <vxlan_rcv+0xc8>
5c23: e8 00 00 00 00 callq 5c28 <vxlan_rcv+0x858>
list->qlen++;
5c28: e9 6b f8 ff ff jmpq 5498 <vxlan_rcv+0xc8>
5c2d: 80 3d 00 00 00 00 00 cmpb $0x0,0x0(%rip) # 5c34 <vxlan_rcv+0x864>
kfree_skb(skb);
return NET_RX_DROP;
}
__skb_queue_tail(&cell->napi_skbs, skb);
if (skb_queue_len(&cell->napi_skbs) == 1)
5c34: 0f 84 cd f9 ff ff je 5607 <vxlan_rcv+0x237>
napi_schedule(&cell->napi);
5c3a: 66 83 fe 02 cmp $0x2,%si
* insure only one NAPI poll instance runs. We also make
* sure there is no pending NAPI disable.
*/
static inline bool napi_schedule_prep(struct napi_struct *n)
{
return !napi_disable_pending(n) &&
5c3e: 0f 84 b8 01 00 00 je 5dfc <vxlan_rcv+0xa2c>
5c44: e8 00 00 00 00 callq 5c49 <vxlan_rcv+0x879>
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __always_inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
{
GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", c);
5c49: 85 c0 test %eax,%eax
5c4b: 0f 84 b6 f9 ff ff je 5607 <vxlan_rcv+0x237>
5c51: 41 be 01 00 00 00 mov $0x1,%r14d
* running.
*/
static inline void napi_schedule(struct napi_struct *n)
{
if (napi_schedule_prep(n))
__napi_schedule(n);
5c57: e9 7b fe ff ff jmpq 5ad7 <vxlan_rcv+0x707>
5c5c: 83 e2 03 and $0x3,%edx
#if IS_ENABLED(CONFIG_IPV6)
else
err = IP6_ECN_decapsulate(oiph, skb);
#endif
if (unlikely(err) && log_ecn_error) {
5c5f: 80 fa 03 cmp $0x3,%dl
5c62: 0f 85 9f f9 ff ff jne 5607 <vxlan_rcv+0x237>
5c68: 66 41 83 f8 08 cmp $0x8,%r8w
if (vxlan_get_sk_family(vs) == AF_INET)
5c6d: 0f 84 27 01 00 00 je 5d9a <vxlan_rcv+0x9ca>
5c73: 66 41 81 f8 86 dd cmp $0xdd86,%r8w
net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
&((struct iphdr *)oiph)->saddr,
((struct iphdr *)oiph)->tos);
else
net_info_ratelimited("non-ECT from %pI6\n",
5c79: 0f 84 98 fe ff ff je 5b17 <vxlan_rcv+0x747>
5c7f: e9 83 f9 ff ff jmpq 5607 <vxlan_rcv+0x237>
5c84: 49 8b 7c 24 20 mov 0x20(%r12),%rdi
5c89: 48 8d 54 31 06 lea 0x6(%rcx,%rsi,1),%rdx
case INET_ECN_CE:
return 2;
}
}
if (INET_ECN_is_ce(outer))
5c8e: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
5c93: e8 98 d6 ff ff callq 3330 <vxlan_snoop>
ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
}
static inline int INET_ECN_set_ce(struct sk_buff *skb)
{
switch (skb->protocol) {
5c98: 84 c0 test %al,%al
5c9a: 0f 85 f0 f7 ff ff jne 5490 <vxlan_rcv+0xc0>
5ca0: 49 8b 8c 24 d0 00 00 mov 0xd0(%r12),%rcx
5ca7: 00
5ca8: 45 0f b7 ac 24 c4 00 movzwl 0xc4(%r12),%r13d
5caf: 00 00
5cb1: e9 2c fd ff ff jmpq 59e2 <vxlan_rcv+0x612>
saddr.sa.sa_family = AF_INET6;
#endif
}
if ((vxlan->flags & VXLAN_F_LEARN) &&
vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source))
5cb6: 42 8b 44 29 0c mov 0xc(%rcx,%r13,1),%eax
5cbb: ba 02 00 00 00 mov $0x2,%edx
5cc0: 66 89 54 24 30 mov %dx,0x30(%rsp)
5cc5: 89 44 24 34 mov %eax,0x34(%rsp)
saddr.sin6.sin6_addr = ipv6_hdr(skb)->saddr;
saddr.sa.sa_family = AF_INET6;
#endif
}
if ((vxlan->flags & VXLAN_F_LEARN) &&
5cc9: e9 07 fd ff ff jmpq 59d5 <vxlan_rcv+0x605>
5cce: 0f b7 c0 movzwl %ax,%eax
5cd1: 0f b6 7c 01 01 movzbl 0x1(%rcx,%rax,1),%edi
5cd6: e9 48 fd ff ff jmpq 5a23 <vxlan_rcv+0x653>
5cdb: 44 89 f0 mov %r14d,%eax
5cde: 41 80 8c 24 91 00 00 orb $0x6,0x91(%r12)
5ce5: 00 06
if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
return false;
/* Get address from the outer IP header */
if (vxlan_get_sk_family(vs) == AF_INET) {
saddr.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
5ce7: 25 fe ff 00 00 and $0xfffe,%eax
saddr.sa.sa_family = AF_INET;
5cec: 4c 01 d0 add %r10,%rax
5cef: 48 29 f0 sub %rsi,%rax
5cf2: 66 41 89 84 24 98 00 mov %ax,0x98(%r12)
5cf9: 00 00
if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
return false;
/* Get address from the outer IP header */
if (vxlan_get_sk_family(vs) == AF_INET) {
saddr.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
5cfb: 0f b7 44 24 18 movzwl 0x18(%rsp),%eax
struct sk_buff *skb)
{
__u8 inner;
if (skb->protocol == htons(ETH_P_IP))
inner = ip_hdr(skb)->tos;
5d00: 44 29 f0 sub %r14d,%eax
5d03: 66 41 89 84 24 9a 00 mov %ax,0x9a(%r12)
5d0a: 00 00
static inline void skb_remcsum_adjust_partial(struct sk_buff *skb, void *ptr,
u16 start, u16 offset)
{
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = ((unsigned char *)ptr + start) - skb->head;
5d0c: 41 8b 97 1c 20 00 00 mov 0x201c(%r15),%edx
} while (0)
static inline void skb_remcsum_adjust_partial(struct sk_buff *skb, void *ptr,
u16 start, u16 offset)
{
skb->ip_summed = CHECKSUM_PARTIAL;
5d13: e9 61 fb ff ff jmpq 5879 <vxlan_rcv+0x4a9>
skb->csum_start = ((unsigned char *)ptr + start) - skb->head;
5d18: 39 c7 cmp %eax,%edi
5d1a: 89 54 24 08 mov %edx,0x8(%rsp)
5d1e: 44 89 6c 24 20 mov %r13d,0x20(%rsp)
5d23: 4c 89 44 24 10 mov %r8,0x10(%rsp)
5d28: 0f 82 62 f7 ff ff jb 5490 <vxlan_rcv+0xc0>
skb->csum_offset = offset - start;
5d2e: 29 f0 sub %esi,%eax
5d30: 4c 89 e7 mov %r12,%rdi
5d33: 89 c6 mov %eax,%esi
5d35: e8 00 00 00 00 callq 5d3a <vxlan_rcv+0x96a>
5d3a: 48 85 c0 test %rax,%rax
5d3d: 4c 8b 44 24 10 mov 0x10(%rsp),%r8
5d42: 44 8b 4c 24 20 mov 0x20(%rsp),%r9d
5d47: 8b 54 24 08 mov 0x8(%rsp),%edx
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
5d4b: 0f 84 3f f7 ff ff je 5490 <vxlan_rcv+0xc0>
5d51: e9 5d fa ff ff jmpq 57b3 <vxlan_rcv+0x3e3>
5d56: 31 d2 xor %edx,%edx
5d58: be 0e 00 00 00 mov $0xe,%esi
5d5d: e8 00 00 00 00 callq 5d62 <vxlan_rcv+0x992>
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
5d62: 41 0f b7 b4 24 c6 00 movzwl 0xc6(%r12),%esi
5d69: 00 00
goto out;
start = vxlan_rco_start(unparsed->vx_vni);
offset = start + vxlan_rco_offset(unparsed->vx_vni);
if (!pskb_may_pull(skb, offset + sizeof(u16)))
5d6b: 49 8b 8c 24 d0 00 00 mov 0xd0(%r12),%rcx
5d72: 00
5d73: f7 d0 not %eax
5d75: 89 c2 mov %eax,%edx
5d77: 41 8b 84 24 98 00 00 mov 0x98(%r12),%eax
5d7e: 00
5d7f: 01 d0 add %edx,%eax
5d81: 83 d0 00 adc $0x0,%eax
5d84: 41 89 84 24 98 00 00 mov %eax,0x98(%r12)
5d8b: 00
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_block_sub(skb->csum,
5d8c: 48 8d 3c 31 lea (%rcx,%rsi,1),%rdi
5d90: e9 e1 fb ff ff jmpq 5976 <vxlan_rcv+0x5a6>
5d95: e8 00 00 00 00 callq 5d9a <vxlan_rcv+0x9ca>
5d9a: 41 8b 94 24 c8 00 00 mov 0xc8(%r12),%edx
5da1: 00
5da2: 48 01 c8 add %rcx,%rax
5da5: 48 8d 70 14 lea 0x14(%rax),%rsi
5da9: 48 01 d1 add %rdx,%rcx
5dac: 48 39 ce cmp %rcx,%rsi
5daf: 0f 87 52 f8 ff ff ja 5607 <vxlan_rcv+0x237>
5db5: 0f b6 70 01 movzbl 0x1(%rax),%esi
5db9: 0f b7 78 0a movzwl 0xa(%rax),%edi
5dbd: 89 f1 mov %esi,%ecx
5dbf: 83 c6 01 add $0x1,%esi
5dc2: 89 f2 mov %esi,%edx
5dc4: 83 e2 03 and $0x3,%edx
drop:
/* Consume bad packet */
kfree_skb(skb);
return 0;
}
5dc7: 40 80 e6 02 and $0x2,%sil
static inline int INET_ECN_set_ce(struct sk_buff *skb)
{
switch (skb->protocol) {
case cpu_to_be16(ETH_P_IP):
if (skb_network_header(skb) + sizeof(struct iphdr) <=
5dcb: 0f 84 36 f8 ff ff je 5607 <vxlan_rcv+0x237>
5dd1: 66 c1 c2 08 rol $0x8,%dx
5dd5: 31 f6 xor %esi,%esi
5dd7: 0f b7 d2 movzwl %dx,%edx
5dda: 8d 94 17 ff fb 00 00 lea 0xfbff(%rdi,%rdx,1),%edx
5de1: 81 fa fe ff 00 00 cmp $0xfffe,%edx
} while (0)
static inline int IP_ECN_set_ce(struct iphdr *iph)
{
u32 check = (__force u32)iph->check;
u32 ecn = (iph->tos + 1) & INET_ECN_MASK;
5de7: 40 0f 97 c6 seta %sil
(label) |= htonl(INET_ECN_ECT_0 << 20); \
} while (0)
static inline int IP_ECN_set_ce(struct iphdr *iph)
{
u32 check = (__force u32)iph->check;
5deb: 83 c9 03 or $0x3,%ecx
u32 ecn = (iph->tos + 1) & INET_ECN_MASK;
5dee: 01 f2 add %esi,%edx
5df0: 88 48 01 mov %cl,0x1(%rax)
5df3: 66 89 50 0a mov %dx,0xa(%rax)
* INET_ECN_NOT_ECT => 01
* INET_ECN_ECT_1 => 10
* INET_ECN_ECT_0 => 11
* INET_ECN_CE => 00
*/
if (!(ecn & 2))
5df7: e9 0b f8 ff ff jmpq 5607 <vxlan_rcv+0x237>
5dfc: e8 00 00 00 00 callq 5e01 <vxlan_rcv+0xa31>
/*
* The following gives us:
* INET_ECN_ECT_1 => check += htons(0xFFFD)
* INET_ECN_ECT_0 => check += htons(0xFFFE)
*/
check += (__force u16)htons(0xFFFB) + (__force u16)htons(ecn);
5e01: 85 c0 test %eax,%eax
5e03: 0f 84 fe f7 ff ff je 5607 <vxlan_rcv+0x237>
5e09: 41 be 01 00 00 00 mov $0x1,%r14d
5e0f: 41 0f b6 55 01 movzbl 0x1(%r13),%edx
iph->check = (__force __sum16)(check + (check>=0xFFFF));
5e14: 49 8d 75 0c lea 0xc(%r13),%rsi
5e18: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
5e1f: e8 00 00 00 00 callq 5e24 <vxlan_rcv+0xa54>
5e24: e9 be fc ff ff jmpq 5ae7 <vxlan_rcv+0x717>
5e29: f0 48 ff 82 e8 01 00 lock incq 0x1e8(%rdx)
5e30: 00
err = IP6_ECN_decapsulate(oiph, skb);
#endif
if (unlikely(err) && log_ecn_error) {
if (vxlan_get_sk_family(vs) == AF_INET)
net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
5e31: 4c 89 e7 mov %r12,%rdi
5e34: e8 00 00 00 00 callq 5e39 <vxlan_rcv+0xa69>
5e39: e9 5a f6 ff ff jmpq 5498 <vxlan_rcv+0xc8>
5e3e: 4c 89 e7 mov %r12,%rdi
5e41: 4c 89 54 24 08 mov %r10,0x8(%rsp)
5e46: 44 89 4c 24 20 mov %r9d,0x20(%rsp)
5e4b: 4c 89 44 24 10 mov %r8,0x10(%rsp)
5e50: e8 00 00 00 00 callq 5e55 <vxlan_rcv+0xa85>
5e55: 41 0f b6 84 24 91 00 movzbl 0x91(%r12),%eax
5e5c: 00 00
*
* Atomically increments @v by 1.
*/
static __always_inline void atomic64_inc(atomic64_t *v)
{
asm volatile(LOCK_PREFIX "incq %0"
5e5e: 4c 8b 54 24 08 mov 0x8(%rsp),%r10
cell = this_cpu_ptr(gcells->cells);
if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) {
atomic_long_inc(&dev->rx_dropped);
kfree_skb(skb);
5e63: 49 8b bc 24 d8 00 00 mov 0xd8(%r12),%rdi
5e6a: 00
5e6b: 4c 8b 44 24 10 mov 0x10(%rsp),%r8
skb_remcsum_adjust_partial(skb, ptr, start, offset);
return;
}
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
__skb_checksum_complete(skb);
5e70: 44 8b 4c 24 20 mov 0x20(%rsp),%r9d
5e75: 4c 89 d6 mov %r10,%rsi
5e78: 89 c2 mov %eax,%edx
5e7a: 48 29 fe sub %rdi,%rsi
5e7d: 83 e2 06 and $0x6,%edx
5e80: 80 fa 04 cmp $0x4,%dl
5e83: 74 3d je 5ec2 <vxlan_rcv+0xaf2>
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
5e85: 80 fa 06 cmp $0x6,%dl
5e88: 0f 85 58 f9 ff ff jne 57e6 <vxlan_rcv+0x416>
return;
}
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
__skb_checksum_complete(skb);
skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
5e8e: 41 0f b7 94 24 98 00 movzwl 0x98(%r12),%edx
5e95: 00 00
5e97: 49 2b bc 24 d0 00 00 sub 0xd0(%r12),%rdi
5e9e: 00
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
5e9f: 39 fa cmp %edi,%edx
5ea1: 0f 89 3f f9 ff ff jns 57e6 <vxlan_rcv+0x416>
return;
}
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
__skb_checksum_complete(skb);
skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
5ea7: 83 e0 f9 and $0xfffffff9,%eax
5eaa: 41 88 84 24 91 00 00 mov %al,0x91(%r12)
5eb1: 00
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
5eb2: e9 2f f9 ff ff jmpq 57e6 <vxlan_rcv+0x416>
skb->csum = csum_block_sub(skb->csum,
csum_partial(start, len, 0), off);
else if (skb->ip_summed == CHECKSUM_PARTIAL &&
5eb7: 41 be 02 00 00 00 mov $0x2,%r14d
5ebd: e9 4d ff ff ff jmpq 5e0f <vxlan_rcv+0xa3f>
5ec2: 31 d2 xor %edx,%edx
5ec4: e8 00 00 00 00 callq 5ec9 <vxlan_rcv+0xaf9>
5ec9: 45 8b 9c 24 98 00 00 mov 0x98(%r12),%r11d
5ed0: 00
5ed1: f7 d0 not %eax
5ed3: 4c 8b 44 24 10 mov 0x10(%rsp),%r8
skb_checksum_start_offset(skb) < 0)
skb->ip_summed = CHECKSUM_NONE;
5ed8: 41 01 c3 add %eax,%r11d
5edb: 41 83 d3 00 adc $0x0,%r11d
5edf: 44 8b 4c 24 20 mov 0x20(%rsp),%r9d
5ee4: 45 89 9c 24 98 00 00 mov %r11d,0x98(%r12)
5eeb: 00
return 0;
case INET_ECN_ECT_0:
case INET_ECN_ECT_1:
return 1;
case INET_ECN_CE:
return 2;
5eec: 4c 8b 54 24 08 mov 0x8(%rsp),%r10
5ef1: e9 f8 f8 ff ff jmpq 57ee <vxlan_rcv+0x41e>
static __always_inline void
__skb_postpull_rcsum(struct sk_buff *skb, const void *start, unsigned int len,
unsigned int off)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_block_sub(skb->csum,
5ef6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
5efd: 00 00 00
0000000000005f00 <vxlan_xmit>:
5f00: e8 00 00 00 00 callq 5f05 <vxlan_xmit+0x5>
5f05: 55 push %rbp
5f06: 48 89 e5 mov %rsp,%rbp
5f09: 41 57 push %r15
5f0b: 41 56 push %r14
5f0d: 41 55 push %r13
5f0f: 41 54 push %r12
5f11: 49 89 f6 mov %rsi,%r14
5f14: 53 push %rbx
5f15: 48 89 fb mov %rdi,%rbx
5f18: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
5f1c: 48 83 ec 60 sub $0x60,%rsp
5f20: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
5f27: 00 00
5f29: 48 89 44 24 58 mov %rax,0x58(%rsp)
5f2e: 31 c0 xor %eax,%eax
* Outer IP header inherits ECN and DF from inner header.
* Outer UDP destination is the VXLAN assigned port.
* source port is based on hash of flow
*/
static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
{
5f30: 48 8b 47 58 mov 0x58(%rdi),%rax
5f34: 48 83 e0 fe and $0xfffffffffffffffe,%rax
5f38: 0f 84 fc 04 00 00 je 643a <vxlan_xmit+0x53a>
5f3e: f6 40 61 02 testb $0x2,0x61(%rax)
5f42: 0f 84 52 01 00 00 je 609a <vxlan_xmit+0x19a>
5f48: 48 05 a0 00 00 00 add $0xa0,%rax
5f4e: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
5f55: 48 8b 93 d8 00 00 00 mov 0xd8(%rbx),%rdx
5f5c: 48 29 ca sub %rcx,%rdx
5f5f: 66 89 93 c6 00 00 00 mov %dx,0xc6(%rbx)
static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
{
struct metadata_dst *md_dst = (struct metadata_dst *) skb_dst(skb);
if (md_dst && md_dst->dst.flags & DST_METADATA)
5f66: 41 8b b6 d8 08 00 00 mov 0x8d8(%r14),%esi
5f6d: f7 c6 00 20 00 00 test $0x2000,%esi
5f73: 0f 85 e6 00 00 00 jne 605f <vxlan_xmit+0x15f>
{
struct metadata_dst *md_dst = skb_metadata_dst(skb);
struct dst_entry *dst;
if (md_dst)
return &md_dst->u.tun_info;
5f79: 83 e6 02 and $0x2,%esi
5f7c: 4d 8d ae 40 08 00 00 lea 0x840(%r14),%r13
return skb->mac_header != (typeof(skb->mac_header))~0U;
}
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data - skb->head;
5f83: 74 20 je 5fa5 <vxlan_xmit+0xa5>
5f85: 0f b7 d2 movzwl %dx,%edx
5f88: 0f b7 44 11 0c movzwl 0xc(%rcx,%rdx,1),%eax
5f8d: 66 c1 c0 08 rol $0x8,%ax
5f91: 66 3d 06 08 cmp $0x806,%ax
5f95: 0f 84 cf 04 00 00 je 646a <vxlan_xmit+0x56a>
info = skb_tunnel_info(skb);
skb_reset_mac_header(skb);
if (vxlan->flags & VXLAN_F_COLLECT_METADATA) {
5f9b: 66 3d dd 86 cmp $0x86dd,%ax
5f9f: 0f 84 77 02 00 00 je 621c <vxlan_xmit+0x31c>
5fa5: 44 0f b7 bb c6 00 00 movzwl 0xc6(%rbx),%r15d
5fac: 00
*
* Get network device private data
*/
static inline void *netdev_priv(const struct net_device *dev)
{
return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
5fad: 4c 89 ef mov %r13,%rdi
5fb0: 49 01 cf add %rcx,%r15
else
kfree_skb(skb);
return NETDEV_TX_OK;
}
if (vxlan->flags & VXLAN_F_PROXY) {
5fb3: 4c 89 fe mov %r15,%rsi
eth = eth_hdr(skb);
if (ntohs(eth->h_proto) == ETH_P_ARP)
5fb6: e8 45 a0 ff ff callq 0 <__vxlan_find_mac>
5fbb: 48 85 c0 test %rax,%rax
5fbe: 49 89 c4 mov %rax,%r12
5fc1: 0f 84 24 02 00 00 je 61eb <vxlan_xmit+0x2eb>
5fc7: 41 80 7c 24 48 00 cmpb $0x0,0x48(%r12)
return arp_reduce(dev, skb);
#if IS_ENABLED(CONFIG_IPV6)
else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
5fcd: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 5fd4 <vxlan_xmit+0xd4>
5fd4: c6 44 24 18 00 movb $0x0,0x18(%rsp)
skb->network_header += offset;
}
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
return skb->head + skb->mac_header;
5fd9: 49 89 44 24 28 mov %rax,0x28(%r12)
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
5fde: 0f 88 e0 00 00 00 js 60c4 <vxlan_xmit+0x1c4>
5fe4: 49 8b 44 24 30 mov 0x30(%r12),%rax
5fe9: 49 83 c4 30 add $0x30,%r12
if (f)
5fed: 49 39 c4 cmp %rax,%r12
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
5ff0: 4c 8d 78 d8 lea -0x28(%rax),%r15
if (f)
5ff4: 74 6f je 6065 <vxlan_xmit+0x165>
5ff6: 0f b6 44 24 18 movzbl 0x18(%rsp),%eax
eth = eth_hdr(skb);
f = vxlan_find_mac(vxlan, eth->h_dest);
did_rsc = false;
if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
5ffb: 4d 89 fd mov %r15,%r13
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
if (f)
f->used = jiffies;
5ffe: 89 44 24 20 mov %eax,0x20(%rsp)
6002: 49 8b 47 28 mov 0x28(%r15),%rax
#endif
}
eth = eth_hdr(skb);
f = vxlan_find_mac(vxlan, eth->h_dest);
did_rsc = false;
6006: 49 39 c4 cmp %rax,%r12
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
if (f)
f->used = jiffies;
6009: 4c 8d 78 d8 lea -0x28(%rax),%r15
600d: 74 36 je 6045 <vxlan_xmit+0x145>
eth = eth_hdr(skb);
f = vxlan_find_mac(vxlan, eth->h_dest);
did_rsc = false;
if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
600f: 4d 85 ed test %r13,%r13
6012: 74 7e je 6092 <vxlan_xmit+0x192>
6014: be 20 00 08 02 mov $0x2080020,%esi
kfree_skb(skb);
return NETDEV_TX_OK;
}
}
list_for_each_entry_rcu(rdst, &f->remotes, list) {
6019: 48 89 df mov %rbx,%rdi
601c: e8 00 00 00 00 callq 6021 <vxlan_xmit+0x121>
6021: 48 85 c0 test %rax,%rax
6024: 74 dc je 6002 <vxlan_xmit+0x102>
fdst = rdst;
continue;
}
skb1 = skb_clone(skb, GFP_ATOMIC);
if (skb1)
vxlan_xmit_one(skb1, dev, rdst, did_rsc);
6026: 8b 4c 24 20 mov 0x20(%rsp),%ecx
602a: 4c 89 fa mov %r15,%rdx
kfree_skb(skb);
return NETDEV_TX_OK;
}
}
list_for_each_entry_rcu(rdst, &f->remotes, list) {
602d: 48 89 c7 mov %rax,%rdi
fdst = rdst;
continue;
}
skb1 = skb_clone(skb, GFP_ATOMIC);
if (skb1)
vxlan_xmit_one(skb1, dev, rdst, did_rsc);
6030: 4c 89 f6 mov %r14,%rsi
6033: e8 e8 e1 ff ff callq 4220 <vxlan_xmit_one>
kfree_skb(skb);
return NETDEV_TX_OK;
}
}
list_for_each_entry_rcu(rdst, &f->remotes, list) {
6038: 49 8b 47 28 mov 0x28(%r15),%rax
603c: 49 39 c4 cmp %rax,%r12
struct sk_buff *skb1;
if (!fdst) {
603f: 4c 8d 78 d8 lea -0x28(%rax),%r15
6043: 75 ca jne 600f <vxlan_xmit+0x10f>
fdst = rdst;
continue;
}
skb1 = skb_clone(skb, GFP_ATOMIC);
6045: 4d 85 ed test %r13,%r13
6048: 74 1b je 6065 <vxlan_xmit+0x165>
604a: 0f b6 4c 24 18 movzbl 0x18(%rsp),%ecx
604f: 4c 89 ea mov %r13,%rdx
if (skb1)
6052: 4c 89 f6 mov %r14,%rsi
6055: 48 89 df mov %rbx,%rdi
vxlan_xmit_one(skb1, dev, rdst, did_rsc);
6058: e8 c3 e1 ff ff callq 4220 <vxlan_xmit_one>
605d: eb 0e jmp 606d <vxlan_xmit+0x16d>
605f: f6 40 49 01 testb $0x1,0x49(%rax)
6063: 75 4e jne 60b3 <vxlan_xmit+0x1b3>
6065: 48 89 df mov %rbx,%rdi
6068: e8 00 00 00 00 callq 606d <vxlan_xmit+0x16d>
kfree_skb(skb);
return NETDEV_TX_OK;
}
}
list_for_each_entry_rcu(rdst, &f->remotes, list) {
606d: 31 c0 xor %eax,%eax
606f: 48 8b 4c 24 58 mov 0x58(%rsp),%rcx
6074: 65 48 33 0c 25 28 00 xor %gs:0x28,%rcx
607b: 00 00
if (skb1)
vxlan_xmit_one(skb1, dev, rdst, did_rsc);
}
if (fdst)
vxlan_xmit_one(skb, dev, fdst, did_rsc);
607d: 0f 85 52 08 00 00 jne 68d5 <vxlan_xmit+0x9d5>
6083: 48 8d 65 d8 lea -0x28(%rbp),%rsp
6087: 5b pop %rbx
6088: 41 5c pop %r12
608a: 41 5d pop %r13
608c: 41 5e pop %r14
608e: 41 5f pop %r15
info = skb_tunnel_info(skb);
skb_reset_mac_header(skb);
if (vxlan->flags & VXLAN_F_COLLECT_METADATA) {
if (info && info->mode & IP_TUNNEL_INFO_TX)
6090: 5d pop %rbp
6091: c3 retq
6092: 4d 89 fd mov %r15,%r13
if ((vxlan->flags & VXLAN_F_L2MISS) &&
!is_multicast_ether_addr(eth->h_dest))
vxlan_fdb_miss(vxlan, eth->h_dest);
dev->stats.tx_dropped++;
kfree_skb(skb);
6095: e9 68 ff ff ff jmpq 6002 <vxlan_xmit+0x102>
609a: 48 8b 80 90 00 00 00 mov 0x90(%rax),%rax
if (fdst)
vxlan_xmit_one(skb, dev, fdst, did_rsc);
else
kfree_skb(skb);
return NETDEV_TX_OK;
}
60a1: 48 85 c0 test %rax,%rax
60a4: 0f 84 90 03 00 00 je 643a <vxlan_xmit+0x53a>
60aa: 48 83 c0 1c add $0x1c,%rax
60ae: e9 9b fe ff ff jmpq 5f4e <vxlan_xmit+0x4e>
60b3: 31 c9 xor %ecx,%ecx
60b5: 31 d2 xor %edx,%edx
60b7: 4c 89 f6 mov %r14,%rsi
60ba: 48 89 df mov %rbx,%rdi
60bd: e8 5e e1 ff ff callq 4220 <vxlan_xmit_one>
kfree_skb(skb);
return NETDEV_TX_OK;
}
}
list_for_each_entry_rcu(rdst, &f->remotes, list) {
60c2: eb a9 jmp 606d <vxlan_xmit+0x16d>
60c4: 41 f6 86 d8 08 00 00 testb $0x4,0x8d8(%r14)
60cb: 04
dst = skb_dst(skb);
if (dst && dst->lwtstate)
60cc: 0f 84 12 ff ff ff je 5fe4 <vxlan_xmit+0xe4>
60d2: 41 0f b7 47 0c movzwl 0xc(%r15),%eax
60d7: 66 c1 c0 08 rol $0x8,%ax
info->options_len = len;
}
static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstate)
{
return (struct ip_tunnel_info *)lwtstate->data;
60db: 66 3d 00 08 cmp $0x800,%ax
60df: 74 0a je 60eb <vxlan_xmit+0x1eb>
60e1: 66 3d dd 86 cmp $0x86dd,%ax
skb_reset_mac_header(skb);
if (vxlan->flags & VXLAN_F_COLLECT_METADATA) {
if (info && info->mode & IP_TUNNEL_INFO_TX)
vxlan_xmit_one(skb, dev, NULL, false);
60e5: 0f 85 f9 fe ff ff jne 5fe4 <vxlan_xmit+0xe4>
60eb: 0f b7 83 c6 00 00 00 movzwl 0xc6(%rbx),%eax
60f2: 48 8b 93 d0 00 00 00 mov 0xd0(%rbx),%rdx
eth = eth_hdr(skb);
f = vxlan_find_mac(vxlan, eth->h_dest);
did_rsc = false;
if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
60f9: 48 01 d0 add %rdx,%rax
60fc: f6 00 01 testb $0x1,(%rax)
60ff: 0f 85 f2 05 00 00 jne 66f7 <vxlan_xmit+0x7f7>
(ntohs(eth->h_proto) == ETH_P_IP ||
6105: 0f b7 40 0c movzwl 0xc(%rax),%eax
6109: 66 c1 c0 08 rol $0x8,%ax
eth = eth_hdr(skb);
f = vxlan_find_mac(vxlan, eth->h_dest);
did_rsc = false;
if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
610d: 66 3d 00 08 cmp $0x800,%ax
6111: 0f 84 66 05 00 00 je 667d <vxlan_xmit+0x77d>
6117: 66 3d dd 86 cmp $0x86dd,%ax
611b: 0f 85 d6 05 00 00 jne 66f7 <vxlan_xmit+0x7f7>
6121: 8b 8b 80 00 00 00 mov 0x80(%rbx),%ecx
6127: 89 c8 mov %ecx,%eax
6129: 2b 83 84 00 00 00 sub 0x84(%rbx),%eax
static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct neighbour *n;
if (is_multicast_ether_addr(eth_hdr(skb)->h_dest))
612f: 83 f8 27 cmp $0x27,%eax
6132: 0f 86 39 07 00 00 jbe 6871 <vxlan_xmit+0x971>
return false;
n = NULL;
switch (ntohs(eth_hdr(skb)->h_proto)) {
6138: 44 0f b7 83 c4 00 00 movzwl 0xc4(%rbx),%r8d
613f: 00
6140: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 6147 <vxlan_xmit+0x247>
6147: 48 8b 78 28 mov 0x28(%rax),%rdi
614b: 49 01 d0 add %rdx,%r8
614e: 4c 89 f2 mov %r14,%rdx
6151: 49 8d 70 18 lea 0x18(%r8),%rsi
6155: 4c 89 44 24 20 mov %r8,0x20(%rsp)
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
615a: e8 00 00 00 00 callq 615f <vxlan_xmit+0x25f>
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
615f: 48 85 c0 test %rax,%rax
6162: 4c 8b 44 24 20 mov 0x20(%rsp),%r8
6167: 0f 84 8a 0a 00 00 je 6bf7 <vxlan_xmit+0xcf7>
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
616d: 0f b7 bb c6 00 00 00 movzwl 0xc6(%rbx),%edi
struct ipv6hdr *pip6;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
return false;
pip6 = ipv6_hdr(skb);
n = neigh_lookup(ipv6_stub->nd_tbl, &pip6->daddr, dev);
6174: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
617b: 44 8b 80 b8 00 00 00 mov 0xb8(%rax),%r8d
6182: 48 8d 34 39 lea (%rcx,%rdi,1),%rsi
6186: 0f b7 56 04 movzwl 0x4(%rsi),%edx
618a: 44 8b 0e mov (%rsi),%r9d
618d: 66 33 90 bc 00 00 00 xor 0xbc(%rax),%dx
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
6194: 45 31 c8 xor %r9d,%r8d
6197: 0f b7 d2 movzwl %dx,%edx
619a: 41 09 d0 or %edx,%r8d
skb->network_header += offset;
}
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
return skb->head + skb->mac_header;
619d: 44 89 44 24 20 mov %r8d,0x20(%rsp)
61a2: 0f 85 e1 05 00 00 jne 6789 <vxlan_xmit+0x889>
61a8: f0 ff 48 30 lock decl 0x30(%rax)
* Please note: addr1 & addr2 must both be aligned to u16.
*/
static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
u32 fold = ((*(const u32 *)addr1) ^ (*(const u32 *)addr2)) |
61ac: 0f 84 ca 05 00 00 je 677c <vxlan_xmit+0x87c>
61b2: 8b 44 24 20 mov 0x20(%rsp),%eax
61b6: 85 c0 test %eax,%eax
61b8: 0f 84 39 05 00 00 je 66f7 <vxlan_xmit+0x7f7>
61be: 4c 89 fe mov %r15,%rsi
61c1: 4c 89 ef mov %r13,%rdi
61c4: e8 37 9e ff ff callq 0 <__vxlan_find_mac>
61c9: 48 85 c0 test %rax,%rax
if (n) {
bool diff;
diff = !ether_addr_equal(eth_hdr(skb)->h_dest, n->ha);
if (diff) {
61cc: 49 89 c4 mov %rax,%r12
61cf: 0f 84 f6 06 00 00 je 68cb <vxlan_xmit+0x9cb>
61d5: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 61dc <vxlan_xmit+0x2dc>
* returns true if the result is 0, or false for all other
* cases.
*/
static __always_inline bool atomic_dec_and_test(atomic_t *v)
{
GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", e);
61dc: c6 44 24 18 01 movb $0x1,0x18(%rsp)
61e1: 49 89 44 24 28 mov %rax,0x28(%r12)
if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
(ntohs(eth->h_proto) == ETH_P_IP ||
ntohs(eth->h_proto) == ETH_P_IPV6)) {
did_rsc = route_shortcircuit(dev, skb);
if (did_rsc)
61e6: e9 f9 fd ff ff jmpq 5fe4 <vxlan_xmit+0xe4>
61eb: c6 44 24 18 00 movb $0x0,0x18(%rsp)
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
61f0: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
61f7: 4c 89 ef mov %r13,%rdi
if (f)
61fa: e8 01 9e ff ff callq 0 <__vxlan_find_mac>
61ff: 48 85 c0 test %rax,%rax
6202: 49 89 c4 mov %rax,%r12
f->used = jiffies;
6205: 0f 84 f6 04 00 00 je 6701 <vxlan_xmit+0x801>
620b: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 6212 <vxlan_xmit+0x312>
6212: 49 89 44 24 28 mov %rax,0x28(%r12)
6217: e9 c8 fd ff ff jmpq 5fe4 <vxlan_xmit+0xe4>
#endif
}
eth = eth_hdr(skb);
f = vxlan_find_mac(vxlan, eth->h_dest);
did_rsc = false;
621c: 8b 93 80 00 00 00 mov 0x80(%rbx),%edx
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
6222: 89 d0 mov %edx,%eax
6224: 2b 83 84 00 00 00 sub 0x84(%rbx),%eax
622a: 83 f8 3f cmp $0x3f,%eax
622d: 0f 86 f6 04 00 00 jbe 6729 <vxlan_xmit+0x829>
6233: 0f b7 83 c4 00 00 00 movzwl 0xc4(%rbx),%eax
if (f)
623a: 48 01 c8 add %rcx,%rax
f->used = jiffies;
623d: 80 78 06 3a cmpb $0x3a,0x6(%rax)
6241: 0f 85 5e fd ff ff jne 5fa5 <vxlan_xmit+0xa5>
6247: 44 0f b7 a3 c2 00 00 movzwl 0xc2(%rbx),%r12d
624e: 00
624f: 49 01 cc add %rcx,%r12
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
6252: 66 41 81 3c 24 87 00 cmpw $0x87,(%r12)
6259: 0f 85 46 fd ff ff jne 5fa5 <vxlan_xmit+0xa5>
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
625f: 49 8b 96 08 03 00 00 mov 0x308(%r14),%rdx
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
6266: 48 85 d2 test %rdx,%rdx
6269: 0f 84 f8 03 00 00 je 6667 <vxlan_xmit+0x767>
if (ntohs(eth->h_proto) == ETH_P_ARP)
return arp_reduce(dev, skb);
#if IS_ENABLED(CONFIG_IPV6)
else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
pskb_may_pull(skb, sizeof(struct ipv6hdr)
+ sizeof(struct nd_msg)) &&
626f: 48 ba 00 00 00 00 00 movabs $0x100000000000000,%rdx
6276: 00 00 01
return skb->transport_header != (typeof(skb->transport_header))~0U;
}
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
{
return skb->head + skb->transport_header;
6279: 48 33 50 20 xor 0x20(%rax),%rdx
627d: 48 0b 50 18 or 0x18(%rax),%rdx
6281: 0f 84 e0 03 00 00 je 6667 <vxlan_xmit+0x767>
ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
struct nd_msg *msg;
msg = (struct nd_msg *)skb_transport_header(skb);
if (msg->icmph.icmp6_code == 0 &&
6287: 41 0f b6 44 24 08 movzbl 0x8(%r12),%eax
628d: 3d ff 00 00 00 cmp $0xff,%eax
6292: 0f 84 cf 03 00 00 je 6667 <vxlan_xmit+0x767>
const struct in6_addr *saddr, *daddr;
struct neighbour *n;
struct inet6_dev *in6_dev;
in6_dev = __in6_dev_get(dev);
if (!in6_dev)
6298: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 629f <vxlan_xmit+0x39f>
msg = (struct nd_msg *)skb_transport_header(skb);
if (msg->icmph.icmp6_code != 0 ||
msg->icmph.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION)
goto out;
if (ipv6_addr_loopback(daddr) ||
629f: 49 8d 74 24 08 lea 0x8(%r12),%rsi
62a4: 4c 89 f2 mov %r14,%rdx
62a7: 48 8b 78 28 mov 0x28(%rax),%rdi
62ab: e8 00 00 00 00 callq 62b0 <vxlan_xmit+0x3b0>
62b0: 48 85 c0 test %rax,%rax
62b3: 49 89 c7 mov %rax,%r15
62b6: 0f 84 3b 06 00 00 je 68f7 <vxlan_xmit+0x9f7>
62bc: f6 80 ad 00 00 00 c2 testb $0xc2,0xad(%rax)
62c3: 0f 84 21 06 00 00 je 68ea <vxlan_xmit+0x9ea>
ipv6_addr_is_multicast(&msg->target))
goto out;
n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, dev);
62c9: 48 8d b0 b8 00 00 00 lea 0xb8(%rax),%rsi
62d0: 4c 89 ef mov %r13,%rdi
62d3: e8 28 9d ff ff callq 0 <__vxlan_find_mac>
62d8: 48 85 c0 test %rax,%rax
62db: 0f 84 e7 08 00 00 je 6bc8 <vxlan_xmit+0xcc8>
if (n) {
62e1: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 62e8 <vxlan_xmit+0x3e8>
62e8: 48 89 50 28 mov %rdx,0x28(%rax)
struct vxlan_fdb *f;
struct sk_buff *reply;
if (!(n->nud_state & NUD_CONNECTED)) {
62ec: 48 8b 50 30 mov 0x30(%rax),%rdx
62f0: 66 83 7a d8 0a cmpw $0xa,-0x28(%rdx)
62f5: 0f 84 bd 08 00 00 je 6bb8 <vxlan_xmit+0xcb8>
neigh_release(n);
goto out;
}
f = vxlan_find_mac(vxlan, n->ha);
62fb: 83 7a dc 00 cmpl $0x0,-0x24(%rdx)
62ff: 0f 94 c2 sete %dl
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
6302: 84 d2 test %dl,%dl
6304: 0f 85 e0 05 00 00 jne 68ea <vxlan_xmit+0x9ea>
if (f)
630a: 0f be 40 48 movsbl 0x48(%rax),%eax
630e: c1 e8 1f shr $0x1f,%eax
f->used = jiffies;
6311: 4c 8b 6b 20 mov 0x20(%rbx),%r13
6315: 83 e0 01 and $0x1,%eax
6318: 88 44 24 20 mov %al,0x20(%rsp)
631c: 4d 85 ed test %r13,%r13
631f: 0f 84 c5 05 00 00 je 68ea <vxlan_xmit+0x9ea>
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
6325: 41 0f b7 95 4e 02 00 movzwl 0x24e(%r13),%edx
632c: 00
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
632d: 41 0f b7 85 50 02 00 movzwl 0x250(%r13),%eax
6334: 00
neigh_release(n);
goto out;
}
f = vxlan_find_mac(vxlan, n->ha);
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
6335: 83 c9 ff or $0xffffffff,%ecx
6338: be 20 00 08 02 mov $0x2080020,%esi
neigh_release(n);
goto out;
}
reply = vxlan_na_create(skb, n,
!!(f ? f->flags & NTF_ROUTER : 0));
633d: 01 d0 add %edx,%eax
633f: 41 0f b7 95 52 02 00 movzwl 0x252(%r13),%edx
6346: 00
#if IS_ENABLED(CONFIG_IPV6)
static struct sk_buff *vxlan_na_create(struct sk_buff *request,
struct neighbour *n, bool isrouter)
{
struct net_device *dev = request->dev;
6347: 83 e0 f0 and $0xfffffff0,%eax
634a: 8d 7c 10 58 lea 0x58(%rax,%rdx,1),%edi
u8 *daddr;
int na_olen = 8; /* opt hdr + ETH_ALEN for target */
int ns_olen;
int i, len;
if (dev == NULL)
634e: 31 d2 xor %edx,%edx
6350: e8 00 00 00 00 callq 6355 <vxlan_xmit+0x455>
struct sk_buff *__build_skb(void *data, unsigned int frag_size);
struct sk_buff *build_skb(void *data, unsigned int frag_size);
static inline struct sk_buff *alloc_skb(unsigned int size,
gfp_t priority)
{
return __alloc_skb(size, priority, 0, NUMA_NO_NODE);
6355: 48 85 c0 test %rax,%rax
6358: 49 89 c4 mov %rax,%r12
635b: 0f 84 89 05 00 00 je 68ea <vxlan_xmit+0x9ea>
6361: 66 c7 80 c0 00 00 00 movw $0xdd86,0xc0(%rax)
6368: 86 dd
636a: 4c 89 68 20 mov %r13,0x20(%rax)
636e: be 0e 00 00 00 mov $0xe,%esi
6373: 48 8b 53 20 mov 0x20(%rbx),%rdx
6377: 4c 89 e7 mov %r12,%rdi
637a: 0f b7 8a 4e 02 00 00 movzwl 0x24e(%rdx),%ecx
6381: 0f b7 82 50 02 00 00 movzwl 0x250(%rdx),%eax
6388: 01 c8 add %ecx,%eax
638a: 83 e0 f0 and $0xfffffff0,%eax
return NULL;
len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr) +
sizeof(*na) + na_olen + dev->needed_tailroom;
reply = alloc_skb(len, GFP_ATOMIC);
if (reply == NULL)
638d: 83 c0 10 add $0x10,%eax
6390: 41 01 84 24 c8 00 00 add %eax,0xc8(%r12)
6397: 00
return NULL;
reply->protocol = htons(ETH_P_IPV6);
6398: 48 63 d0 movslq %eax,%rdx
reply->dev = dev;
639b: 49 01 94 24 d8 00 00 add %rdx,0xd8(%r12)
63a2: 00
skb_reserve(reply, LL_RESERVED_SPACE(request->dev));
63a3: e8 00 00 00 00 callq 63a8 <vxlan_xmit+0x4a8>
skb_push(reply, sizeof(struct ethhdr));
63a8: 49 8b 84 24 d0 00 00 mov 0xd0(%r12),%rax
63af: 00
if (reply == NULL)
return NULL;
reply->protocol = htons(ETH_P_IPV6);
reply->dev = dev;
skb_reserve(reply, LL_RESERVED_SPACE(request->dev));
63b0: 49 8b 8c 24 d8 00 00 mov 0xd8(%r12),%rcx
63b7: 00
63b8: 48 29 c1 sub %rax,%rcx
63bb: 66 41 89 8c 24 c6 00 mov %cx,0xc6(%r12)
63c2: 00 00
* room. This is only allowed for an empty buffer.
*/
static inline void skb_reserve(struct sk_buff *skb, int len)
{
skb->data += len;
skb->tail += len;
63c4: 0f b7 93 c2 00 00 00 movzwl 0xc2(%rbx),%edx
* Increase the headroom of an empty &sk_buff by reducing the tail
* room. This is only allowed for an empty buffer.
*/
static inline void skb_reserve(struct sk_buff *skb, int len)
{
skb->data += len;
63cb: 48 8b b3 d0 00 00 00 mov 0xd0(%rbx),%rsi
63d2: 0f b7 bb c6 00 00 00 movzwl 0xc6(%rbx),%edi
return skb->mac_header != (typeof(skb->mac_header))~0U;
}
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data - skb->head;
63d9: 44 8b 9b 80 00 00 00 mov 0x80(%rbx),%r11d
63e0: 48 01 f2 add %rsi,%rdx
63e3: 48 8d 7c 3e 06 lea 0x6(%rsi,%rdi,1),%rdi
63e8: 48 89 d6 mov %rdx,%rsi
63eb: 48 2b b3 d8 00 00 00 sub 0xd8(%rbx),%rsi
63f2: 41 29 f3 sub %esi,%r11d
return skb->transport_header != (typeof(skb->transport_header))~0U;
}
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
{
return skb->head + skb->transport_header;
63f5: 45 8d 53 e7 lea -0x19(%r11),%r10d
63f9: 45 85 d2 test %r10d,%r10d
63fc: 0f 8e 46 05 00 00 jle 6948 <vxlan_xmit+0xa48>
skb_push(reply, sizeof(struct ethhdr));
skb_reset_mac_header(reply);
ns = (struct nd_msg *)skb_transport_header(request);
daddr = eth_hdr(request)->h_source;
6402: 80 7a 18 01 cmpb $0x1,0x18(%rdx)
6406: 0f 84 34 05 00 00 je 6940 <vxlan_xmit+0xa40>
ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns);
for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) {
640c: 31 f6 xor %esi,%esi
640e: eb 0f jmp 641f <vxlan_xmit+0x51f>
6410: 4c 63 c6 movslq %esi,%r8
skb_push(reply, sizeof(struct ethhdr));
skb_reset_mac_header(reply);
ns = (struct nd_msg *)skb_transport_header(request);
daddr = eth_hdr(request)->h_source;
6413: 42 80 7c 02 18 01 cmpb $0x1,0x18(%rdx,%r8,1)
ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns);
for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) {
6419: 0f 84 24 05 00 00 je 6943 <vxlan_xmit+0xa43>
641f: 44 8d 46 01 lea 0x1(%rsi),%r8d
6423: 4d 63 c0 movslq %r8d,%r8
6426: 46 0f b6 44 02 18 movzbl 0x18(%rdx,%r8,1),%r8d
642c: 42 8d 34 c6 lea (%rsi,%r8,8),%esi
6430: 44 39 d6 cmp %r10d,%esi
if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) {
6433: 7c db jl 6410 <vxlan_xmit+0x510>
6435: e9 0e 05 00 00 jmpq 6948 <vxlan_xmit+0xa48>
643a: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
6441: 48 8b 93 d8 00 00 00 mov 0xd8(%rbx),%rdx
6448: 48 29 ca sub %rcx,%rdx
644b: 66 89 93 c6 00 00 00 mov %dx,0xc6(%rbx)
ns = (struct nd_msg *)skb_transport_header(request);
daddr = eth_hdr(request)->h_source;
ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns);
for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) {
6452: 41 8b b6 d8 08 00 00 mov 0x8d8(%r14),%esi
6459: f7 c6 00 20 00 00 test $0x2000,%esi
645f: 0f 85 00 fc ff ff jne 6065 <vxlan_xmit+0x165>
6465: e9 0f fb ff ff jmpq 5f79 <vxlan_xmit+0x79>
return skb->mac_header != (typeof(skb->mac_header))~0U;
}
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data - skb->head;
646a: 41 f6 86 38 02 00 00 testb $0x80,0x238(%r14)
6471: 80
6472: 0f 85 ef 01 00 00 jne 6667 <vxlan_xmit+0x767>
6478: 66 41 83 be 4c 02 00 cmpw $0x18,0x24c(%r14)
647f: 00 18
6481: 41 0f b6 86 75 02 00 movzbl 0x275(%r14),%eax
6488: 00
info = skb_tunnel_info(skb);
skb_reset_mac_header(skb);
if (vxlan->flags & VXLAN_F_COLLECT_METADATA) {
6489: 0f 85 e5 01 00 00 jne 6674 <vxlan_xmit+0x774>
648f: 83 c0 10 add $0x10,%eax
6492: 8b b3 80 00 00 00 mov 0x80(%rbx),%esi
6498: 89 f2 mov %esi,%edx
struct arphdr *parp;
u8 *arpptr, *sha;
__be32 sip, tip;
struct neighbour *n;
if (dev->flags & IFF_NOARP)
649a: 2b 93 84 00 00 00 sub 0x84(%rbx),%edx
64a0: 39 d0 cmp %edx,%eax
64a2: 0f 87 ae 02 00 00 ja 6756 <vxlan_xmit+0x856>
return (struct arphdr *)skb_network_header(skb);
}
static inline int arp_hdr_len(struct net_device *dev)
{
switch (dev->type) {
64a8: 0f b7 83 c4 00 00 00 movzwl 0xc4(%rbx),%eax
64af: 48 01 c1 add %rax,%rcx
64b2: 0f b7 01 movzwl (%rcx),%eax
64b5: 66 3d 00 01 cmp $0x100,%ax
64b9: 74 0a je 64c5 <vxlan_xmit+0x5c5>
64bb: 66 3d 00 06 cmp $0x600,%ax
#if IS_ENABLED(CONFIG_FIREWIRE_NET)
case ARPHRD_IEEE1394:
/* ARP header, device address and 2 IP addresses */
return sizeof(struct arphdr) + dev->addr_len + sizeof(u32) * 2;
64bf: 0f 85 a2 01 00 00 jne 6667 <vxlan_xmit+0x767>
64c5: 66 83 79 02 08 cmpw $0x8,0x2(%rcx)
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
64ca: 0f 85 97 01 00 00 jne 6667 <vxlan_xmit+0x767>
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
64d0: 66 81 79 06 00 01 cmpw $0x100,0x6(%rcx)
64d6: 0f 85 8b 01 00 00 jne 6667 <vxlan_xmit+0x767>
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
64dc: 0f b6 41 04 movzbl 0x4(%rcx),%eax
64e0: 41 3a 86 75 02 00 00 cmp 0x275(%r14),%al
dev->stats.tx_dropped++;
goto out;
}
parp = arp_hdr(skb);
if ((parp->ar_hrd != htons(ARPHRD_ETHER) &&
64e7: 0f 85 7a 01 00 00 jne 6667 <vxlan_xmit+0x767>
64ed: 80 79 05 04 cmpb $0x4,0x5(%rcx)
64f1: 0f 85 70 01 00 00 jne 6667 <vxlan_xmit+0x767>
parp->ar_hrd != htons(ARPHRD_IEEE802)) ||
64f7: 4c 8d 61 08 lea 0x8(%rcx),%r12
64fb: 49 8d 14 04 lea (%r12,%rax,1),%rdx
64ff: 8b 44 02 04 mov 0x4(%rdx,%rax,1),%eax
parp->ar_pro != htons(ETH_P_IP) ||
6503: 8b 0a mov (%rdx),%ecx
6505: 3c 7f cmp $0x7f,%al
6507: 89 4c 24 20 mov %ecx,0x20(%rsp)
650b: 89 44 24 2c mov %eax,0x2c(%rsp)
parp->ar_op != htons(ARPOP_REQUEST) ||
parp->ar_hln != dev->addr_len ||
650f: 0f 84 52 01 00 00 je 6667 <vxlan_xmit+0x767>
parp = arp_hdr(skb);
if ((parp->ar_hrd != htons(ARPHRD_ETHER) &&
parp->ar_hrd != htons(ARPHRD_IEEE802)) ||
parp->ar_pro != htons(ETH_P_IP) ||
parp->ar_op != htons(ARPOP_REQUEST) ||
6515: 25 f0 00 00 00 and $0xf0,%eax
651a: 3d e0 00 00 00 cmp $0xe0,%eax
parp->ar_hln != dev->addr_len ||
651f: 0f 84 42 01 00 00 je 6667 <vxlan_xmit+0x767>
6525: 48 8d 74 24 2c lea 0x2c(%rsp),%rsi
parp->ar_pln != 4)
goto out;
arpptr = (u8 *)parp + sizeof(struct arphdr);
652a: 4c 89 f2 mov %r14,%rdx
sha = arpptr;
arpptr += dev->addr_len; /* sha */
652d: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
memcpy(&sip, arpptr, sizeof(sip));
6534: e8 00 00 00 00 callq 6539 <vxlan_xmit+0x639>
6539: 48 85 c0 test %rax,%rax
arpptr += sizeof(sip);
arpptr += dev->addr_len; /* tha */
memcpy(&tip, arpptr, sizeof(tip));
653c: 49 89 c7 mov %rax,%r15
if (ipv4_is_loopback(tip) ||
653f: 0f 84 f7 06 00 00 je 6c3c <vxlan_xmit+0xd3c>
6545: f6 80 ad 00 00 00 c2 testb $0xc2,0xad(%rax)
654c: 0f 84 98 03 00 00 je 68ea <vxlan_xmit+0x9ea>
6552: 48 8d 90 b8 00 00 00 lea 0xb8(%rax),%rdx
ipv4_is_multicast(tip))
goto out;
n = neigh_lookup(&arp_tbl, &tip, dev);
6559: 4c 89 ef mov %r13,%rdi
655c: 48 89 d6 mov %rdx,%rsi
655f: 48 89 54 24 18 mov %rdx,0x18(%rsp)
6564: e8 97 9a ff ff callq 0 <__vxlan_find_mac>
if (n) {
6569: 48 85 c0 test %rax,%rax
if (ipv4_is_loopback(tip) ||
ipv4_is_multicast(tip))
goto out;
n = neigh_lookup(&arp_tbl, &tip, dev);
656c: 48 8b 54 24 18 mov 0x18(%rsp),%rdx
if (n) {
6571: 74 29 je 659c <vxlan_xmit+0x69c>
6573: 48 8b 0d 00 00 00 00 mov 0x0(%rip),%rcx # 657a <vxlan_xmit+0x67a>
struct vxlan_fdb *f;
struct sk_buff *reply;
if (!(n->nud_state & NUD_CONNECTED)) {
657a: 48 89 48 28 mov %rcx,0x28(%rax)
657e: 48 8b 40 30 mov 0x30(%rax),%rax
neigh_release(n);
goto out;
}
f = vxlan_find_mac(vxlan, n->ha);
6582: 66 83 78 d8 0a cmpw $0xa,-0x28(%rax)
6587: 0f 84 4d 03 00 00 je 68da <vxlan_xmit+0x9da>
static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
658d: 83 78 dc 00 cmpl $0x0,-0x24(%rax)
6591: 0f 94 c0 sete %al
6594: 84 c0 test %al,%al
6596: 0f 85 4e 03 00 00 jne 68ea <vxlan_xmit+0x9ea>
if (f)
659c: 48 89 14 24 mov %rdx,(%rsp)
65a0: 44 8b 44 24 2c mov 0x2c(%rsp),%r8d
f->used = jiffies;
65a5: 4d 89 e1 mov %r12,%r9
65a8: 8b 54 24 20 mov 0x20(%rsp),%edx
65ac: 4c 89 64 24 08 mov %r12,0x8(%rsp)
65b1: 4c 89 f1 mov %r14,%rcx
return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
}
static inline bool vxlan_addr_any(const union vxlan_addr *ipa)
{
if (ipa->sa.sa_family == AF_INET6)
65b4: be 06 08 00 00 mov $0x806,%esi
65b9: bf 02 00 00 00 mov $0x2,%edi
return ipv6_addr_any(&ipa->sin6.sin6_addr);
else
return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
65be: e8 00 00 00 00 callq 65c3 <vxlan_xmit+0x6c3>
65c3: 4c 89 ff mov %r15,%rdi
neigh_release(n);
goto out;
}
f = vxlan_find_mac(vxlan, n->ha);
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
65c6: 49 89 c4 mov %rax,%r12
65c9: e8 72 a2 ff ff callq 840 <neigh_release>
/* bridge-local neighbor */
neigh_release(n);
goto out;
}
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
65ce: 4d 85 e4 test %r12,%r12
65d1: 0f 84 90 00 00 00 je 6667 <vxlan_xmit+0x767>
65d7: 49 8b 8c 24 d8 00 00 mov 0xd8(%r12),%rcx
65de: 00
65df: 49 8b 84 24 d0 00 00 mov 0xd0(%r12),%rax
65e6: 00
65e7: 48 89 ca mov %rcx,%rdx
65ea: 48 29 c2 sub %rax,%rdx
65ed: 66 41 89 94 24 c6 00 mov %dx,0xc6(%r12)
65f4: 00 00
65f6: 41 0f b7 94 24 c4 00 movzwl 0xc4(%r12),%edx
65fd: 00 00
n->ha, sha);
neigh_release(n);
if (reply == NULL)
65ff: 48 01 d0 add %rdx,%rax
6602: 41 8b 94 24 80 00 00 mov 0x80(%r12),%edx
6609: 00
return skb->mac_header != (typeof(skb->mac_header))~0U;
}
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->data - skb->head;
660a: 48 29 c8 sub %rcx,%rax
660d: 29 c2 sub %eax,%edx
660f: 41 3b 94 24 84 00 00 cmp 0x84(%r12),%edx
6616: 00
6617: 41 89 94 24 80 00 00 mov %edx,0x80(%r12)
661e: 00
661f: 0f 82 54 05 00 00 jb 6b79 <vxlan_xmit+0xc79>
6625: 89 c0 mov %eax,%eax
return skb->inner_transport_header - skb->inner_network_header;
}
static inline int skb_network_offset(const struct sk_buff *skb)
{
return skb_network_header(skb) - skb->data;
6627: 41 80 a4 24 90 00 00 andb $0xf8,0x90(%r12)
662e: 00 f8
6630: 4c 89 e7 mov %r12,%rdi
}
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
6633: 48 01 c8 add %rcx,%rax
6636: 49 89 84 24 d8 00 00 mov %rax,0xd8(%r12)
663d: 00
663e: 41 0f b6 84 24 91 00 movzbl 0x91(%r12),%eax
6645: 00 00
6647: 83 e0 f9 and $0xfffffff9,%eax
664a: 83 c8 02 or $0x2,%eax
664d: 41 88 84 24 91 00 00 mov %al,0x91(%r12)
6654: 00
BUG_ON(skb->len < skb->data_len);
return skb->data += len;
6655: e8 00 00 00 00 callq 665a <vxlan_xmit+0x75a>
goto out;
skb_reset_mac_header(reply);
__skb_pull(reply, skb_network_offset(reply));
reply->ip_summed = CHECKSUM_UNNECESSARY;
reply->pkt_type = PACKET_HOST;
665a: 83 e8 01 sub $0x1,%eax
665d: 75 08 jne 6667 <vxlan_xmit+0x767>
665f: 49 83 86 60 01 00 00 addq $0x1,0x160(%r14)
6666: 01
6667: 48 89 df mov %rbx,%rdi
666a: e8 00 00 00 00 callq 666f <vxlan_xmit+0x76f>
if (reply == NULL)
goto out;
skb_reset_mac_header(reply);
__skb_pull(reply, skb_network_offset(reply));
reply->ip_summed = CHECKSUM_UNNECESSARY;
666f: e9 f9 f9 ff ff jmpq 606d <vxlan_xmit+0x16d>
6674: 8d 44 00 10 lea 0x10(%rax,%rax,1),%eax
6678: e9 15 fe ff ff jmpq 6492 <vxlan_xmit+0x592>
667d: 8b 8b 80 00 00 00 mov 0x80(%rbx),%ecx
6683: 89 c8 mov %ecx,%eax
reply->pkt_type = PACKET_HOST;
if (netif_rx_ni(reply) == NET_RX_DROP)
6685: 2b 83 84 00 00 00 sub 0x84(%rbx),%eax
668b: 83 f8 13 cmp $0x13,%eax
668e: 0f 86 0a 02 00 00 jbe 689e <vxlan_xmit+0x99e>
if (reply == NULL)
goto out;
if (netif_rx_ni(reply) == NET_RX_DROP)
dev->stats.rx_dropped++;
6694: 44 0f b7 83 c4 00 00 movzwl 0xc4(%rbx),%r8d
669b: 00
vxlan_ip_miss(dev, &ipa);
}
out:
consume_skb(skb);
669c: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
struct nd_msg *msg;
msg = (struct nd_msg *)skb_transport_header(skb);
if (msg->icmph.icmp6_code == 0 &&
msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
return neigh_reduce(dev, skb);
66a3: 49 01 d0 add %rdx,%r8
#endif
default:
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
return sizeof(struct arphdr) + (dev->addr_len + sizeof(u32)) * 2;
66a6: 4c 89 f2 mov %r14,%rdx
66a9: 49 8d 70 10 lea 0x10(%r8),%rsi
66ad: 4c 89 44 24 20 mov %r8,0x20(%rsp)
66b2: e8 00 00 00 00 callq 66b7 <vxlan_xmit+0x7b7>
return skb->data_len;
}
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
return skb->len - skb->data_len;
66b7: 48 85 c0 test %rax,%rax
66ba: 4c 8b 44 24 20 mov 0x20(%rsp),%r8
return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
}
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
66bf: 0f 85 a8 fa ff ff jne 616d <vxlan_xmit+0x26d>
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
66c5: 41 f6 86 d8 08 00 00 testb $0x10,0x8d8(%r14)
66cc: 10
struct iphdr *pip;
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return false;
pip = ip_hdr(skb);
n = neigh_lookup(&arp_tbl, &pip->daddr, dev);
66cd: 74 28 je 66f7 <vxlan_xmit+0x7f7>
66cf: 48 8d 7c 24 30 lea 0x30(%rsp),%rdi
66d4: b9 07 00 00 00 mov $0x7,%ecx
66d9: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
66de: f3 ab rep stos %eax,%es:(%rdi)
66e0: 66 c7 44 24 30 02 00 movw $0x2,0x30(%rsp)
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
66e7: 4c 89 f7 mov %r14,%rdi
66ea: 41 8b 40 10 mov 0x10(%r8),%eax
66ee: 89 44 24 34 mov %eax,0x34(%rsp)
66f2: e8 59 b9 ff ff callq 2050 <vxlan_ip_miss>
66f7: c6 44 24 18 00 movb $0x0,0x18(%rsp)
66fc: e9 e3 f8 ff ff jmpq 5fe4 <vxlan_xmit+0xe4>
union vxlan_addr ipa = {
6701: 41 f6 86 d8 08 00 00 testb $0x8,0x8d8(%r14)
6708: 08
.sin.sin_addr.s_addr = pip->daddr,
.sin.sin_family = AF_INET,
};
vxlan_ip_miss(dev, &ipa);
6709: 74 11 je 671c <vxlan_xmit+0x81c>
670b: 41 f6 07 01 testb $0x1,(%r15)
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return false;
pip = ip_hdr(skb);
n = neigh_lookup(&arp_tbl, &pip->daddr, dev);
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
union vxlan_addr ipa = {
670f: 75 0b jne 671c <vxlan_xmit+0x81c>
6711: 4c 89 fe mov %r15,%rsi
6714: 4c 89 ef mov %r13,%rdi
.sin.sin_addr.s_addr = pip->daddr,
.sin.sin_family = AF_INET,
};
vxlan_ip_miss(dev, &ipa);
6717: e8 e4 b9 ff ff callq 2100 <vxlan_fdb_miss>
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return false;
pip = ip_hdr(skb);
n = neigh_lookup(&arp_tbl, &pip->daddr, dev);
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
union vxlan_addr ipa = {
671c: 49 83 86 68 01 00 00 addq $0x1,0x168(%r14)
6723: 01
.sin.sin_addr.s_addr = pip->daddr,
.sin.sin_family = AF_INET,
};
vxlan_ip_miss(dev, &ipa);
6724: e9 3c f9 ff ff jmpq 6065 <vxlan_xmit+0x165>
6729: 83 fa 3f cmp $0x3f,%edx
672c: 0f 86 73 f8 ff ff jbe 5fa5 <vxlan_xmit+0xa5>
}
if (f == NULL) {
f = vxlan_find_mac(vxlan, all_zeros_mac);
if (f == NULL) {
if ((vxlan->flags & VXLAN_F_L2MISS) &&
6732: be 40 00 00 00 mov $0x40,%esi
6737: 48 89 df mov %rbx,%rdi
673a: 29 c6 sub %eax,%esi
673c: e8 00 00 00 00 callq 6741 <vxlan_xmit+0x841>
!is_multicast_ether_addr(eth->h_dest))
vxlan_fdb_miss(vxlan, eth->h_dest);
6741: 48 85 c0 test %rax,%rax
6744: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
674b: 0f 84 54 f8 ff ff je 5fa5 <vxlan_xmit+0xa5>
dev->stats.tx_dropped++;
6751: e9 dd fa ff ff jmpq 6233 <vxlan_xmit+0x333>
6756: 39 c6 cmp %eax,%esi
6758: 72 15 jb 676f <vxlan_xmit+0x86f>
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
675a: 29 d0 sub %edx,%eax
675c: 48 89 df mov %rbx,%rdi
675f: 89 c6 mov %eax,%esi
6761: e8 00 00 00 00 callq 6766 <vxlan_xmit+0x866>
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
6766: 48 85 c0 test %rax,%rax
6769: 0f 85 0a 05 00 00 jne 6c79 <vxlan_xmit+0xd79>
676f: 49 83 86 68 01 00 00 addq $0x1,0x168(%r14)
6776: 01
if (vxlan->flags & VXLAN_F_PROXY) {
eth = eth_hdr(skb);
if (ntohs(eth->h_proto) == ETH_P_ARP)
return arp_reduce(dev, skb);
#if IS_ENABLED(CONFIG_IPV6)
else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
6777: e9 eb fe ff ff jmpq 6667 <vxlan_xmit+0x767>
677c: 48 89 c7 mov %rax,%rdi
677f: e8 00 00 00 00 callq 6784 <vxlan_xmit+0x884>
6784: e9 29 fa ff ff jmpq 61b2 <vxlan_xmit+0x2b2>
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
6789: 41 0f b6 96 75 02 00 movzbl 0x275(%r14),%edx
6790: 00
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
6791: 4c 8d 46 06 lea 0x6(%rsi),%r8
6795: 83 fa 08 cmp $0x8,%edx
struct neighbour *n;
if (dev->flags & IFF_NOARP)
goto out;
if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
6798: 0f 83 a3 00 00 00 jae 6841 <vxlan_xmit+0x941>
679e: f6 c2 04 test $0x4,%dl
dev->stats.tx_dropped++;
67a1: 0f 85 d4 03 00 00 jne 6b7b <vxlan_xmit+0xc7b>
67a7: 85 d2 test %edx,%edx
67a9: 74 25 je 67d0 <vxlan_xmit+0x8d0>
67ab: 0f b6 0e movzbl (%rsi),%ecx
*/
static inline void neigh_release(struct neighbour *neigh)
{
if (atomic_dec_and_test(&neigh->refcnt))
neigh_destroy(neigh);
67ae: f6 c2 02 test $0x2,%dl
67b1: 88 4e 06 mov %cl,0x6(%rsi)
67b4: 0f 85 15 04 00 00 jne 6bcf <vxlan_xmit+0xccf>
if (n) {
bool diff;
diff = !ether_addr_equal(eth_hdr(skb)->h_dest, n->ha);
if (diff) {
memcpy(eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
67ba: 0f b7 bb c6 00 00 00 movzwl 0xc6(%rbx),%edi
67c1: 41 0f b6 96 75 02 00 movzbl 0x275(%r14),%edx
67c8: 00
67c9: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
67d0: 48 01 f9 add %rdi,%rcx
67d3: 83 fa 08 cmp $0x8,%edx
67d6: 48 8d b0 b8 00 00 00 lea 0xb8(%rax),%rsi
67dd: 73 31 jae 6810 <vxlan_xmit+0x910>
67df: f6 c2 04 test $0x4,%dl
67e2: 0f 85 bd 03 00 00 jne 6ba5 <vxlan_xmit+0xca5>
67e8: 85 d2 test %edx,%edx
67ea: 0f 84 b8 f9 ff ff je 61a8 <vxlan_xmit+0x2a8>
67f0: 0f b6 3e movzbl (%rsi),%edi
67f3: f6 c2 02 test $0x2,%dl
67f6: 40 88 39 mov %dil,(%rcx)
67f9: 0f 84 a9 f9 ff ff je 61a8 <vxlan_xmit+0x2a8>
67ff: 89 d2 mov %edx,%edx
dev->addr_len);
memcpy(eth_hdr(skb)->h_dest, n->ha, dev->addr_len);
6801: 0f b7 74 16 fe movzwl -0x2(%rsi,%rdx,1),%esi
6806: 66 89 74 11 fe mov %si,-0x2(%rcx,%rdx,1)
680b: e9 98 f9 ff ff jmpq 61a8 <vxlan_xmit+0x2a8>
6810: 48 8b b8 b8 00 00 00 mov 0xb8(%rax),%rdi
6817: 48 89 39 mov %rdi,(%rcx)
681a: 89 d7 mov %edx,%edi
681c: 4c 8b 44 3e f8 mov -0x8(%rsi,%rdi,1),%r8
6821: 4c 89 44 39 f8 mov %r8,-0x8(%rcx,%rdi,1)
6826: 48 8d 79 08 lea 0x8(%rcx),%rdi
682a: 48 83 e7 f8 and $0xfffffffffffffff8,%rdi
682e: 48 29 f9 sub %rdi,%rcx
6831: 48 29 ce sub %rcx,%rsi
6834: 01 d1 add %edx,%ecx
6836: c1 e9 03 shr $0x3,%ecx
6839: f3 48 a5 rep movsq %ds:(%rsi),%es:(%rdi)
683c: e9 67 f9 ff ff jmpq 61a8 <vxlan_xmit+0x2a8>
6841: 48 8b 0e mov (%rsi),%rcx
6844: 48 89 4e 06 mov %rcx,0x6(%rsi)
6848: 89 d1 mov %edx,%ecx
684a: 48 8b 7c 0e f8 mov -0x8(%rsi,%rcx,1),%rdi
684f: 49 89 7c 08 f8 mov %rdi,-0x8(%r8,%rcx,1)
6854: 48 8d 7e 0e lea 0xe(%rsi),%rdi
6858: 48 83 e7 f8 and $0xfffffffffffffff8,%rdi
685c: 49 29 f8 sub %rdi,%r8
685f: 42 8d 0c 02 lea (%rdx,%r8,1),%ecx
6863: 4c 29 c6 sub %r8,%rsi
6866: c1 e9 03 shr $0x3,%ecx
6869: f3 48 a5 rep movsq %ds:(%rsi),%es:(%rdi)
686c: e9 49 ff ff ff jmpq 67ba <vxlan_xmit+0x8ba>
if (n) {
bool diff;
diff = !ether_addr_equal(eth_hdr(skb)->h_dest, n->ha);
if (diff) {
memcpy(eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
6871: 83 f9 27 cmp $0x27,%ecx
6874: 0f 86 7d fe ff ff jbe 66f7 <vxlan_xmit+0x7f7>
687a: be 28 00 00 00 mov $0x28,%esi
687f: 48 89 df mov %rbx,%rdi
6882: 29 c6 sub %eax,%esi
6884: e8 00 00 00 00 callq 6889 <vxlan_xmit+0x989>
6889: 48 85 c0 test %rax,%rax
688c: 0f 84 65 fe ff ff je 66f7 <vxlan_xmit+0x7f7>
6892: 48 8b 93 d0 00 00 00 mov 0xd0(%rbx),%rdx
6899: e9 9a f8 ff ff jmpq 6138 <vxlan_xmit+0x238>
689e: 83 f9 13 cmp $0x13,%ecx
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
68a1: 0f 86 50 fe ff ff jbe 66f7 <vxlan_xmit+0x7f7>
68a7: be 14 00 00 00 mov $0x14,%esi
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
68ac: 48 89 df mov %rbx,%rdi
68af: 29 c6 sub %eax,%esi
68b1: e8 00 00 00 00 callq 68b6 <vxlan_xmit+0x9b6>
68b6: 48 85 c0 test %rax,%rax
#if IS_ENABLED(CONFIG_IPV6)
case ETH_P_IPV6:
{
struct ipv6hdr *pip6;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
68b9: 0f 84 38 fe ff ff je 66f7 <vxlan_xmit+0x7f7>
68bf: 48 8b 93 d0 00 00 00 mov 0xd0(%rbx),%rdx
68c6: e9 c9 fd ff ff jmpq 6694 <vxlan_xmit+0x794>
68cb: c6 44 24 18 01 movb $0x1,0x18(%rsp)
static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
if (likely(len <= skb_headlen(skb)))
return 1;
if (unlikely(len > skb->len))
68d0: e9 1b f9 ff ff jmpq 61f0 <vxlan_xmit+0x2f0>
68d5: e8 00 00 00 00 callq 68da <vxlan_xmit+0x9da>
return 0;
return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL;
68da: 48 8b 48 e0 mov -0x20(%rax),%rcx
68de: 48 0b 48 e8 or -0x18(%rax),%rcx
68e2: 0f 94 c0 sete %al
68e5: e9 aa fc ff ff jmpq 6594 <vxlan_xmit+0x694>
switch (ntohs(eth_hdr(skb)->h_proto)) {
case ETH_P_IP:
{
struct iphdr *pip;
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
68ea: 4c 89 ff mov %r15,%rdi
68ed: e8 4e 9f ff ff callq 840 <neigh_release>
68f2: e9 70 fd ff ff jmpq 6667 <vxlan_xmit+0x767>
68f7: 41 f6 86 d8 08 00 00 testb $0x10,0x8d8(%r14)
68fe: 10
const u8 *mac)
{
struct vxlan_fdb *f;
f = __vxlan_find_mac(vxlan, mac);
if (f)
68ff: 0f 84 62 fd ff ff je 6667 <vxlan_xmit+0x767>
if (fdst)
vxlan_xmit_one(skb, dev, fdst, did_rsc);
else
kfree_skb(skb);
return NETDEV_TX_OK;
}
6905: 48 8d 7c 24 30 lea 0x30(%rsp),%rdi
static inline bool ipv6_addr_any(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
const unsigned long *ul = (const unsigned long *)a;
return (ul[0] | ul[1]) == 0UL;
690a: 31 c0 xor %eax,%eax
690c: b9 07 00 00 00 mov $0x7,%ecx
6911: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
6916: f3 ab rep stos %eax,%es:(%rdi)
6918: 66 c7 44 24 30 0a 00 movw $0xa,0x30(%rsp)
}
reply = vxlan_na_create(skb, n,
!!(f ? f->flags & NTF_ROUTER : 0));
neigh_release(n);
691f: 4c 89 f7 mov %r14,%rdi
6922: 49 8b 44 24 08 mov 0x8(%r12),%rax
goto out;
if (netif_rx_ni(reply) == NET_RX_DROP)
dev->stats.rx_dropped++;
} else if (vxlan->flags & VXLAN_F_L3MISS) {
6927: 49 8b 54 24 10 mov 0x10(%r12),%rdx
692c: 48 89 44 24 38 mov %rax,0x38(%rsp)
6931: 48 89 54 24 40 mov %rdx,0x40(%rsp)
union vxlan_addr ipa = {
6936: e8 15 b7 ff ff callq 2050 <vxlan_ip_miss>
693b: e9 27 fd ff ff jmpq 6667 <vxlan_xmit+0x767>
6940: 45 31 c0 xor %r8d,%r8d
.sin6.sin6_addr = msg->target,
.sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
6943: 4a 8d 7c 02 1a lea 0x1a(%rdx,%r8,1),%rdi
if (netif_rx_ni(reply) == NET_RX_DROP)
dev->stats.rx_dropped++;
} else if (vxlan->flags & VXLAN_F_L3MISS) {
union vxlan_addr ipa = {
6948: 0f b7 c9 movzwl %cx,%ecx
694b: be 0e 00 00 00 mov $0xe,%esi
.sin6.sin6_addr = msg->target,
.sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
6950: 48 89 54 24 10 mov %rdx,0x10(%rsp)
if (netif_rx_ni(reply) == NET_RX_DROP)
dev->stats.rx_dropped++;
} else if (vxlan->flags & VXLAN_F_L3MISS) {
union vxlan_addr ipa = {
6955: 48 01 c8 add %rcx,%rax
6958: 8b 0f mov (%rdi),%ecx
695a: 89 08 mov %ecx,(%rax)
695c: 0f b7 4f 04 movzwl 0x4(%rdi),%ecx
6960: 4c 89 e7 mov %r12,%rdi
6963: 66 89 48 04 mov %cx,0x4(%rax)
.sin6.sin6_addr = msg->target,
.sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
6967: 41 0f b7 84 24 c6 00 movzwl 0xc6(%r12),%eax
696e: 00 00
6970: 49 03 84 24 d0 00 00 add 0xd0(%r12),%rax
6977: 00
skb->network_header += offset;
}
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
{
return skb->head + skb->mac_header;
6978: 41 8b 8f b8 00 00 00 mov 0xb8(%r15),%ecx
ether_addr_copy(eth_hdr(reply)->h_dest, daddr);
ether_addr_copy(eth_hdr(reply)->h_source, n->ha);
eth_hdr(reply)->h_proto = htons(ETH_P_IPV6);
reply->protocol = htons(ETH_P_IPV6);
skb_pull(reply, sizeof(struct ethhdr));
697f: 89 48 06 mov %ecx,0x6(%rax)
6982: 41 0f b7 8f bc 00 00 movzwl 0xbc(%r15),%ecx
6989: 00
* Please note: dst & src must both be aligned to u16.
*/
static inline void ether_addr_copy(u8 *dst, const u8 *src)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
*(u32 *)dst = *(const u32 *)src;
698a: 66 89 48 0a mov %cx,0xa(%rax)
*(u16 *)(dst + 4) = *(const u16 *)(src + 4);
698e: 41 0f b7 84 24 c6 00 movzwl 0xc6(%r12),%eax
6995: 00 00
6997: 49 8b 8c 24 d0 00 00 mov 0xd0(%r12),%rcx
699e: 00
699f: 66 c7 44 01 0c 86 dd movw $0xdd86,0xc(%rcx,%rax,1)
69a6: 66 41 c7 84 24 c0 00 movw $0xdd86,0xc0(%r12)
69ad: 00 00 86 dd
* Please note: dst & src must both be aligned to u16.
*/
static inline void ether_addr_copy(u8 *dst, const u8 *src)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
*(u32 *)dst = *(const u32 *)src;
69b1: e8 00 00 00 00 callq 69b6 <vxlan_xmit+0xab6>
*(u16 *)(dst + 4) = *(const u16 *)(src + 4);
69b6: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
69bd: 00
}
/* Ethernet header */
ether_addr_copy(eth_hdr(reply)->h_dest, daddr);
ether_addr_copy(eth_hdr(reply)->h_source, n->ha);
eth_hdr(reply)->h_proto = htons(ETH_P_IPV6);
69be: 49 2b 84 24 d0 00 00 sub 0xd0(%r12),%rax
69c5: 00
69c6: be 28 00 00 00 mov $0x28,%esi
69cb: 4c 89 e7 mov %r12,%rdi
69ce: 66 41 89 84 24 c4 00 mov %ax,0xc4(%r12)
69d5: 00 00
reply->protocol = htons(ETH_P_IPV6);
69d7: e8 00 00 00 00 callq 69dc <vxlan_xmit+0xadc>
69dc: 45 0f b7 ac 24 c4 00 movzwl 0xc4(%r12),%r13d
69e3: 00 00
skb_pull(reply, sizeof(struct ethhdr));
69e5: 45 31 c0 xor %r8d,%r8d
return skb->head + skb->network_header;
}
static inline void skb_reset_network_header(struct sk_buff *skb)
{
skb->network_header = skb->data - skb->head;
69e8: b9 0a 00 00 00 mov $0xa,%ecx
69ed: 4d 03 ac 24 d0 00 00 add 0xd0(%r12),%r13
69f4: 00
69f5: 44 89 c0 mov %r8d,%eax
skb_reset_network_header(reply);
skb_put(reply, sizeof(struct ipv6hdr));
69f8: 44 89 44 24 18 mov %r8d,0x18(%rsp)
69fd: 4c 89 ef mov %r13,%rdi
6a00: f3 ab rep stos %eax,%es:(%rdi)
6a02: b9 60 00 00 00 mov $0x60,%ecx
6a07: 41 88 4d 00 mov %cl,0x0(%r13)
6a0b: 0f b7 83 c4 00 00 00 movzwl 0xc4(%rbx),%eax
skb->transport_header += offset;
}
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
{
return skb->head + skb->network_header;
6a12: 48 8b b3 d0 00 00 00 mov 0xd0(%rbx),%rsi
/* IPv6 header */
pip6 = ipv6_hdr(reply);
memset(pip6, 0, sizeof(struct ipv6hdr));
6a19: 0f b6 04 06 movzbl (%rsi,%rax,1),%eax
6a1d: 41 c6 45 06 3a movb $0x3a,0x6(%r13)
6a22: 41 c6 45 07 ff movb $0xff,0x7(%r13)
6a27: 83 e0 0f and $0xf,%eax
6a2a: 09 c8 or %ecx,%eax
6a2c: 41 88 45 00 mov %al,0x0(%r13)
6a30: 0f b7 83 c4 00 00 00 movzwl 0xc4(%rbx),%eax
pip6->version = 6;
6a37: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
pip6->priority = ipv6_hdr(request)->priority;
6a3e: 48 8b 74 01 08 mov 0x8(%rcx,%rax,1),%rsi
6a43: 48 8b 7c 01 10 mov 0x10(%rcx,%rax,1),%rdi
6a48: 49 89 75 18 mov %rsi,0x18(%r13)
6a4c: 49 89 7d 20 mov %rdi,0x20(%r13)
pip6->nexthdr = IPPROTO_ICMPV6;
6a50: 49 8b b7 90 01 00 00 mov 0x190(%r15),%rsi
/* IPv6 header */
pip6 = ipv6_hdr(reply);
memset(pip6, 0, sizeof(struct ipv6hdr));
pip6->version = 6;
pip6->priority = ipv6_hdr(request)->priority;
6a57: 49 8b bf 98 01 00 00 mov 0x198(%r15),%rdi
6a5e: 49 89 75 08 mov %rsi,0x8(%r13)
pip6->nexthdr = IPPROTO_ICMPV6;
pip6->hop_limit = 255;
pip6->daddr = ipv6_hdr(request)->saddr;
6a62: 49 89 7d 10 mov %rdi,0x10(%r13)
6a66: be 28 00 00 00 mov $0x28,%esi
6a6b: 4c 89 e7 mov %r12,%rdi
6a6e: e8 00 00 00 00 callq 6a73 <vxlan_xmit+0xb73>
6a73: 49 8b 84 24 d8 00 00 mov 0xd8(%r12),%rax
6a7a: 00
6a7b: 49 2b 84 24 d0 00 00 sub 0xd0(%r12),%rax
6a82: 00
pip6->saddr = *(struct in6_addr *)n->primary_key;
6a83: be 20 00 00 00 mov $0x20,%esi
6a88: 4c 89 e7 mov %r12,%rdi
6a8b: 66 41 89 84 24 c2 00 mov %ax,0xc2(%r12)
6a92: 00 00
6a94: e8 00 00 00 00 callq 6a99 <vxlan_xmit+0xb99>
skb_pull(reply, sizeof(struct ipv6hdr));
6a99: 44 8b 44 24 18 mov 0x18(%rsp),%r8d
6a9e: 49 89 c2 mov %rax,%r10
6aa1: 48 89 c7 mov %rax,%rdi
return skb->head + skb->transport_header;
}
static inline void skb_reset_transport_header(struct sk_buff *skb)
{
skb->transport_header = skb->data - skb->head;
6aa4: b9 08 00 00 00 mov $0x8,%ecx
6aa9: 48 8b 54 24 10 mov 0x10(%rsp),%rdx
6aae: be 20 00 00 00 mov $0x20,%esi
skb_reset_transport_header(reply);
na = (struct nd_msg *)skb_put(reply, sizeof(*na) + na_olen);
6ab3: 44 89 c0 mov %r8d,%eax
6ab6: f3 ab rep stos %eax,%es:(%rdi)
6ab8: 0f b6 44 24 20 movzbl 0x20(%rsp),%eax
6abd: 41 c6 02 88 movb $0x88,(%r10)
6ac1: 4c 89 d7 mov %r10,%rdi
6ac4: 4c 89 54 24 20 mov %r10,0x20(%rsp)
/* Neighbor Advertisement */
memset(na, 0, sizeof(*na)+na_olen);
6ac9: c1 e0 07 shl $0x7,%eax
6acc: 83 c8 60 or $0x60,%eax
pip6->saddr = *(struct in6_addr *)n->primary_key;
skb_pull(reply, sizeof(struct ipv6hdr));
skb_reset_transport_header(reply);
na = (struct nd_msg *)skb_put(reply, sizeof(*na) + na_olen);
6acf: 41 88 42 04 mov %al,0x4(%r10)
/* Neighbor Advertisement */
memset(na, 0, sizeof(*na)+na_olen);
6ad3: 48 8b 42 08 mov 0x8(%rdx),%rax
6ad7: 48 8b 52 10 mov 0x10(%rdx),%rdx
na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
na->icmph.icmp6_router = isrouter;
na->icmph.icmp6_override = 1;
na->icmph.icmp6_solicited = 1;
na->target = ns->target;
6adb: 49 89 42 08 mov %rax,0x8(%r10)
ether_addr_copy(&na->opt[2], n->ha);
na->opt[0] = ND_OPT_TARGET_LL_ADDR;
na->opt[1] = na_olen >> 3;
na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr,
6adf: 49 89 52 10 mov %rdx,0x10(%r10)
skb_reset_transport_header(reply);
na = (struct nd_msg *)skb_put(reply, sizeof(*na) + na_olen);
/* Neighbor Advertisement */
memset(na, 0, sizeof(*na)+na_olen);
6ae3: 41 8b 87 b8 00 00 00 mov 0xb8(%r15),%eax
na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
na->icmph.icmp6_router = isrouter;
6aea: 31 d2 xor %edx,%edx
6aec: 41 89 42 1a mov %eax,0x1a(%r10)
na = (struct nd_msg *)skb_put(reply, sizeof(*na) + na_olen);
/* Neighbor Advertisement */
memset(na, 0, sizeof(*na)+na_olen);
na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
6af0: 41 0f b7 87 bc 00 00 movzwl 0xbc(%r15),%eax
6af7: 00
na->target = ns->target;
ether_addr_copy(&na->opt[2], n->ha);
na->opt[0] = ND_OPT_TARGET_LL_ADDR;
na->opt[1] = na_olen >> 3;
na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr,
6af8: 41 c6 42 18 02 movb $0x2,0x18(%r10)
/* Neighbor Advertisement */
memset(na, 0, sizeof(*na)+na_olen);
na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
na->icmph.icmp6_router = isrouter;
na->icmph.icmp6_override = 1;
na->icmph.icmp6_solicited = 1;
6afd: 41 c6 42 19 01 movb $0x1,0x19(%r10)
6b02: 66 41 89 42 1e mov %ax,0x1e(%r10)
na->target = ns->target;
6b07: e8 00 00 00 00 callq 6b0c <vxlan_xmit+0xc0c>
6b0c: 49 8d 75 18 lea 0x18(%r13),%rsi
6b10: 49 8d 7d 08 lea 0x8(%r13),%rdi
* Please note: dst & src must both be aligned to u16.
*/
static inline void ether_addr_copy(u8 *dst, const u8 *src)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
*(u32 *)dst = *(const u32 *)src;
6b14: 41 89 c0 mov %eax,%r8d
6b17: b9 3a 00 00 00 mov $0x3a,%ecx
6b1c: ba 20 00 00 00 mov $0x20,%edx
*(u16 *)(dst + 4) = *(const u16 *)(src + 4);
6b21: e8 00 00 00 00 callq 6b26 <vxlan_xmit+0xc26>
6b26: 4c 8b 54 24 20 mov 0x20(%rsp),%r10
ether_addr_copy(&na->opt[2], n->ha);
na->opt[0] = ND_OPT_TARGET_LL_ADDR;
6b2b: be 28 00 00 00 mov $0x28,%esi
na->opt[1] = na_olen >> 3;
6b30: 4c 89 e7 mov %r12,%rdi
6b33: 66 41 89 42 02 mov %ax,0x2(%r10)
na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr,
6b38: 66 41 c7 45 04 00 20 movw $0x2000,0x4(%r13)
&pip6->daddr, sizeof(*na)+na_olen, IPPROTO_ICMPV6,
6b3f: e8 00 00 00 00 callq 6b44 <vxlan_xmit+0xc44>
na->target = ns->target;
ether_addr_copy(&na->opt[2], n->ha);
na->opt[0] = ND_OPT_TARGET_LL_ADDR;
na->opt[1] = na_olen >> 3;
na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr,
6b44: 41 0f b6 84 24 91 00 movzbl 0x91(%r12),%eax
6b4b: 00 00
6b4d: 4c 89 ff mov %r15,%rdi
6b50: 83 e0 f9 and $0xfffffff9,%eax
6b53: 83 c8 02 or $0x2,%eax
6b56: 41 88 84 24 91 00 00 mov %al,0x91(%r12)
6b5d: 00
&pip6->daddr, sizeof(*na)+na_olen, IPPROTO_ICMPV6,
csum_partial(na, sizeof(*na)+na_olen, 0));
pip6->payload_len = htons(sizeof(*na)+na_olen);
skb_push(reply, sizeof(struct ipv6hdr));
6b5e: e8 dd 9c ff ff callq 840 <neigh_release>
na->target = ns->target;
ether_addr_copy(&na->opt[2], n->ha);
na->opt[0] = ND_OPT_TARGET_LL_ADDR;
na->opt[1] = na_olen >> 3;
na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr,
6b63: 4c 89 e7 mov %r12,%rdi
6b66: e8 00 00 00 00 callq 6b6b <vxlan_xmit+0xc6b>
&pip6->daddr, sizeof(*na)+na_olen, IPPROTO_ICMPV6,
csum_partial(na, sizeof(*na)+na_olen, 0));
pip6->payload_len = htons(sizeof(*na)+na_olen);
6b6b: 83 e8 01 sub $0x1,%eax
6b6e: 0f 85 f3 fa ff ff jne 6667 <vxlan_xmit+0x767>
skb_push(reply, sizeof(struct ipv6hdr));
reply->ip_summed = CHECKSUM_UNNECESSARY;
6b74: e9 e6 fa ff ff jmpq 665f <vxlan_xmit+0x75f>
6b79: 0f 0b ud2
6b7b: 89 d2 mov %edx,%edx
}
reply = vxlan_na_create(skb, n,
!!(f ? f->flags & NTF_ROUTER : 0));
neigh_release(n);
6b7d: 44 89 4e 06 mov %r9d,0x6(%rsi)
pip6->payload_len = htons(sizeof(*na)+na_olen);
skb_push(reply, sizeof(struct ipv6hdr));
reply->ip_summed = CHECKSUM_UNNECESSARY;
6b81: 8b 4c 16 fc mov -0x4(%rsi,%rdx,1),%ecx
6b85: 41 89 4c 10 fc mov %ecx,-0x4(%r8,%rdx,1)
6b8a: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
}
reply = vxlan_na_create(skb, n,
!!(f ? f->flags & NTF_ROUTER : 0));
neigh_release(n);
6b91: 0f b7 bb c6 00 00 00 movzwl 0xc6(%rbx),%edi
if (reply == NULL)
goto out;
if (netif_rx_ni(reply) == NET_RX_DROP)
6b98: 41 0f b6 96 75 02 00 movzbl 0x275(%r14),%edx
6b9f: 00
6ba0: e9 2b fc ff ff jmpq 67d0 <vxlan_xmit+0x8d0>
6ba5: 8b 3e mov (%rsi),%edi
6ba7: 89 d2 mov %edx,%edx
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len);
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
BUG_ON(skb->len < skb->data_len);
6ba9: 89 39 mov %edi,(%rcx)
if (n) {
bool diff;
diff = !ether_addr_equal(eth_hdr(skb)->h_dest, n->ha);
if (diff) {
memcpy(eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
6bab: 8b 74 16 fc mov -0x4(%rsi,%rdx,1),%esi
6baf: 89 74 11 fc mov %esi,-0x4(%rcx,%rdx,1)
6bb3: e9 f0 f5 ff ff jmpq 61a8 <vxlan_xmit+0x2a8>
6bb8: 48 8b 4a e0 mov -0x20(%rdx),%rcx
6bbc: 48 0b 4a e8 or -0x18(%rdx),%rcx
6bc0: 0f 94 c2 sete %dl
6bc3: e9 3a f7 ff ff jmpq 6302 <vxlan_xmit+0x402>
6bc8: 31 c0 xor %eax,%eax
6bca: e9 42 f7 ff ff jmpq 6311 <vxlan_xmit+0x411>
6bcf: 89 d2 mov %edx,%edx
6bd1: 0f b7 4c 16 fe movzwl -0x2(%rsi,%rdx,1),%ecx
dev->addr_len);
memcpy(eth_hdr(skb)->h_dest, n->ha, dev->addr_len);
6bd6: 66 41 89 4c 10 fe mov %cx,-0x2(%r8,%rdx,1)
6bdc: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
6be3: 0f b7 bb c6 00 00 00 movzwl 0xc6(%rbx),%edi
6bea: 41 0f b6 96 75 02 00 movzbl 0x275(%r14),%edx
6bf1: 00
6bf2: e9 d9 fb ff ff jmpq 67d0 <vxlan_xmit+0x8d0>
6bf7: 41 f6 86 d8 08 00 00 testb $0x10,0x8d8(%r14)
6bfe: 10
if (n) {
bool diff;
diff = !ether_addr_equal(eth_hdr(skb)->h_dest, n->ha);
if (diff) {
memcpy(eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
6bff: 0f 84 f2 fa ff ff je 66f7 <vxlan_xmit+0x7f7>
6c05: 48 8d 7c 24 30 lea 0x30(%rsp),%rdi
6c0a: b9 07 00 00 00 mov $0x7,%ecx
6c0f: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
6c14: f3 ab rep stos %eax,%es:(%rdi)
6c16: 66 c7 44 24 30 0a 00 movw $0xa,0x30(%rsp)
6c1d: 4c 89 f7 mov %r14,%rdi
6c20: 49 8b 40 18 mov 0x18(%r8),%rax
6c24: 49 8b 50 20 mov 0x20(%r8),%rdx
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
return false;
pip6 = ipv6_hdr(skb);
n = neigh_lookup(ipv6_stub->nd_tbl, &pip6->daddr, dev);
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
6c28: 48 89 44 24 38 mov %rax,0x38(%rsp)
6c2d: 48 89 54 24 40 mov %rdx,0x40(%rsp)
6c32: e8 19 b4 ff ff callq 2050 <vxlan_ip_miss>
union vxlan_addr ipa = {
6c37: e9 bb fa ff ff jmpq 66f7 <vxlan_xmit+0x7f7>
6c3c: 41 f6 86 d8 08 00 00 testb $0x10,0x8d8(%r14)
6c43: 10
6c44: 0f 84 1d fa ff ff je 6667 <vxlan_xmit+0x767>
6c4a: 48 8d 7c 24 30 lea 0x30(%rsp),%rdi
.sin6.sin6_addr = pip6->daddr,
.sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
6c4f: 31 c0 xor %eax,%eax
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
return false;
pip6 = ipv6_hdr(skb);
n = neigh_lookup(ipv6_stub->nd_tbl, &pip6->daddr, dev);
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
union vxlan_addr ipa = {
6c51: b9 07 00 00 00 mov $0x7,%ecx
6c56: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
6c5b: f3 ab rep stos %eax,%es:(%rdi)
6c5d: 8b 44 24 2c mov 0x2c(%rsp),%eax
6c61: 4c 89 f7 mov %r14,%rdi
.sin6.sin6_addr = pip6->daddr,
.sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
6c64: 66 c7 44 24 30 02 00 movw $0x2,0x30(%rsp)
6c6b: 89 44 24 34 mov %eax,0x34(%rsp)
reply->ip_summed = CHECKSUM_UNNECESSARY;
reply->pkt_type = PACKET_HOST;
if (netif_rx_ni(reply) == NET_RX_DROP)
dev->stats.rx_dropped++;
} else if (vxlan->flags & VXLAN_F_L3MISS) {
6c6f: e8 dc b3 ff ff callq 2050 <vxlan_ip_miss>
6c74: e9 ee f9 ff ff jmpq 6667 <vxlan_xmit+0x767>
6c79: 48 8b 8b d0 00 00 00 mov 0xd0(%rbx),%rcx
union vxlan_addr ipa = {
6c80: e9 23 f8 ff ff jmpq 64a8 <vxlan_xmit+0x5a8>
Disassembly of section .init.text:
0000000000000000 <init_module>:
0: 55 push %rbp
1: be 04 00 00 00 mov $0x4,%esi
6: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
d: 48 89 e5 mov %rsp,%rbp
10: 41 54 push %r12
12: 53 push %rbx
13: e8 00 00 00 00 callq 18 <init_module+0x18>
18: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
1f: e8 00 00 00 00 callq 24 <init_module+0x24>
24: 85 c0 test %eax,%eax
26: 41 89 c4 mov %eax,%r12d
29: 75 41 jne 6c <init_module+0x6c>
2b: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
}
/* Look up Ethernet address in forwarding table */
static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
32: e8 00 00 00 00 callq 37 <init_module+0x37>
struct hlist_head *head = vxlan_fdb_head(vxlan, mac);
struct vxlan_fdb *f;
hlist_for_each_entry_rcu(f, head, hlist) {
37: 85 c0 test %eax,%eax
39: 89 c3 mov %eax,%ebx
3b: 75 21 jne 5e <init_module+0x5e>
3d: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
}
/* Look up Ethernet address in forwarding table */
static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
const u8 *mac)
{
44: e8 00 00 00 00 callq 49 <init_module+0x49>
struct hlist_head *head = vxlan_fdb_head(vxlan, mac);
struct vxlan_fdb *f;
hlist_for_each_entry_rcu(f, head, hlist) {
49: 89 c3 mov %eax,%ebx
4b: 44 89 e0 mov %r12d,%eax
4e: 85 db test %ebx,%ebx
50: 74 1a je 6c <init_module+0x6c>
52: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
59: e8 00 00 00 00 callq 5e <init_module+0x5e>
5e: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
65: e8 00 00 00 00 callq 6a <init_module+0x6a>
if (ether_addr_equal(mac, f->eth_addr))
6a: 89 d8 mov %ebx,%eax
6c: 5b pop %rbx
6d: 41 5c pop %r12
6f: 5d pop %rbp
70: c3 retq
Disassembly of section .exit.text:
0000000000000000 <cleanup_module>:
0: 55 push %rbp
1: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
8: 48 89 e5 mov %rsp,%rbp
b: e8 00 00 00 00 callq 10 <cleanup_module+0x10>
10: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
17: e8 00 00 00 00 callq 1c <cleanup_module+0x1c>
1c: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
23: e8 00 00 00 00 callq 28 <cleanup_module+0x28>
28: 5d pop %rbp
29: c3 retq
^ permalink raw reply [flat|nested] 6+ messages in thread