blob: cbfad99bce2522143c6f5c536dba2226536d03b0 [file] [log] [blame]
Andrea Campanella715a4c42022-06-01 15:39:46 +02001# SPDX-FileCopyrightText: 2022-present Intel Corporation
2# SPDX-License-Identifier: Apache-2.0
3
4from mininet.node import Host, Node
5import socket
6import struct
7
8DBUF_DROP_TIMEOUT_SEC = "30s"
9DBUF_NUM_QUEUES = 10
10DBUF_MAX_PKTS_PER_QUEUE = 16
11
12
13def ip2long(ip):
14 """
15 Convert an IP string to long
16 """
17 packedIP = socket.inet_aton(ip)
18 return struct.unpack("!L", packedIP)[0]
19
20
21class IPv4Host(Host):
22 """Host that can be configured with an IPv4 gateway (default route).
23 """
24
25 def config(self, mac=None, ip=None, defaultRoute=None, lo='up', gw=None, **_params):
26 super(IPv4Host, self).config(mac, ip, defaultRoute, lo, **_params)
27 self.cmd('ip -4 addr flush dev %s' % self.defaultIntf())
28 self.cmd('ip -6 addr flush dev %s' % self.defaultIntf())
29 self.cmd('sysctl -w net.ipv4.ip_forward=0')
30 self.cmd('ip -4 link set up %s' % self.defaultIntf())
31 self.cmd('ip -4 addr add %s dev %s' % (ip, self.defaultIntf()))
32 if gw:
33 self.cmd('ip -4 route add default via %s' % gw)
34 # Disable offload
35 for attr in ["rx", "tx", "sg"]:
36 cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf(), attr)
37 self.cmd(cmd)
38
39 def updateIP():
40 return ip.split('/')[0]
41
42 self.defaultIntf().updateIP = updateIP
43
44
45class TaggedIPv4Host(Host):
46 """VLAN-tagged host that can be configured with an IPv4 gateway
47 (default route).
48 """
49 vlanIntf = None
50
51 def config(self, mac=None, ip=None, defaultRoute=None, lo='up', gw=None,
52 vlan=None, **_params):
53 super(TaggedIPv4Host, self).config(mac, ip, defaultRoute, lo, **_params)
54 self.vlanIntf = "%s.%s" % (self.defaultIntf(), vlan)
55 # Replace default interface with a tagged one
56 self.cmd('ip -4 addr flush dev %s' % self.defaultIntf())
57 self.cmd('ip -6 addr flush dev %s' % self.defaultIntf())
58 self.cmd('ip -4 link add link %s name %s type vlan id %s' % (
59 self.defaultIntf(), self.vlanIntf, vlan))
60 self.cmd('ip -4 link set up %s' % self.vlanIntf)
61 self.cmd('ip -4 addr add %s dev %s' % (ip, self.vlanIntf))
62 if gw:
63 self.cmd('ip -4 route add default via %s' % gw)
64
65 self.defaultIntf().name = self.vlanIntf
66 self.nameToIntf[self.vlanIntf] = self.defaultIntf()
67
68 # Disable offload
69 for attr in ["rx", "tx", "sg"]:
70 cmd = "/sbin/ethtool --offload %s %s off" % (
71 self.defaultIntf(), attr)
72 self.cmd(cmd)
73
74 def updateIP():
75 return ip.split('/')[0]
76
77 self.defaultIntf().updateIP = updateIP
78
79 def terminate(self):
80 self.cmd('ip -4 link remove link %s' % self.vlanIntf)
81 super(TaggedIPv4Host, self).terminate()
82
83class DbufHost(IPv4Host):
84
85 def __init__(self, name, inNamespace=False, **params):
86 super(DbufHost, self).__init__(name, inNamespace, **params)
87
88 def config(self, drainIp=None, drainMac=None, **_params):
89 super(DbufHost, self).config(**_params)
90 self.setDrainIpAndMac(self.defaultIntf(), drainIp, drainMac)
91 self.startDbuf()
92
93 def startDbuf(self):
94 args = map(str, [
95 "-max_queues",
96 DBUF_NUM_QUEUES,
97 "-max_packet_slots_per_queue",
98 DBUF_MAX_PKTS_PER_QUEUE,
99 "-queue_drop_timeout",
100 DBUF_DROP_TIMEOUT_SEC,
101 ])
102 # Send to background
103 cmd = '/usr/local/bin/dbuf %s > /tmp/dbuf_%s.log 2>&1 &' \
104 % (" ".join(args), self.name)
105 print(cmd)
106 self.cmd(cmd)
107
108 def setDrainIpAndMac(self, intf, drainIp=None, drainMac=None):
109 if drainIp:
110 self.setHostRoute(drainIp, intf)
111 if drainMac:
112 self.setARP(drainIp, drainMac)
113
114
115class DualHomedIpv4Host(Host):
116 """A dual homed host that can be configured with an IPv4 gateway (default route).
117 """
118
119 def __init__(self, name, **kwargs):
120 super(DualHomedIpv4Host, self).__init__(name, **kwargs)
121 self.bond0 = None
122
123 def config(self, ip=None, gw=None, **kwargs):
124 super(DualHomedIpv4Host, self).config(**kwargs)
125 intf0 = self.intfs[0].name
126 intf1 = self.intfs[1].name
127 self.bond0 = "%s-bond0" % self.name
128 self.cmd('modprobe bonding')
129 self.cmd('ip link add %s type bond miimon 100 mode balance-xor xmit_hash_policy layer2+3' %
130 self.bond0)
131 self.cmd('ip link set %s down' % intf0)
132 self.cmd('ip link set %s down' % intf1)
133 self.cmd('ip link set %s master %s' % (intf0, self.bond0))
134 self.cmd('ip link set %s master %s' % (intf1, self.bond0))
135 self.cmd('ip addr flush dev %s' % intf0)
136 self.cmd('ip addr flush dev %s' % intf1)
137 self.cmd('ip link set %s up' % self.bond0)
138
139 self.cmd('sysctl -w net.ipv4.ip_forward=0')
140 self.cmd('ip -4 addr add %s dev %s' % (ip, self.bond0))
141 if gw:
142 self.cmd('ip -4 route add default via %s' % gw)
143 # Disable offload
144 for attr in ["rx", "tx", "sg"]:
145 cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf(), attr)
146 self.cmd(cmd)
147
148 def terminate(self, **kwargs):
149 self.cmd('ip link set %s down' % self.bond0)
150 self.cmd('ip link delete %s' % self.bond0)
151 super(DualHomedIpv4Host, self).terminate()
152
153
154class DualHomedDbufHost(DualHomedIpv4Host, DbufHost):
155
156 def __init__(self, name, inNamespace=False, **params):
157 super(DualHomedDbufHost, self).__init__(name, inNamespace=inNamespace, **params)
158
159 def config(self, drainIp=None, drainMac=None, **_params):
160 super(DualHomedDbufHost, self).config(**_params)
161 self.setDrainIpAndMac(self.bond0, drainIp, drainMac)