3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
5 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
10 from socket
import AF_UNSPEC
11 from socket
import AF_BRIDGE
12 from iff
import IFF_UP
13 from rtnetlink
import *
17 class rtnetlinkApi(RtNetlink
):
21 def __init__(self
, pid
):
22 RtNetlink
.__init
__(self
, pid
)
23 self
.logger
= logging
.getLogger('ifupdown.' +
24 self
.__class
__.__name
__)
35 def get_ifindex(self
, ifname
):
36 ifindex
= self
.ifindexmap
.get(ifname
)
38 with
open('/sys/class/net/%s/ifindex' %ifname
, 'r') as f
:
39 ifindex
= int(f
.read())
40 self
.ifindexmap
[ifname
] = ifindex
43 def create_vlan(self
, link
, ifname
, vlanid
):
44 self
.logger
.info('rtnetlink: creating vlan interface %s' %ifname
)
45 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
48 ifindex
= self
.get_ifindex(link
)
50 raise Exception('cannot determine ifindex for link %s (%s)'
53 ifm
= Ifinfomsg(AF_UNSPEC
)
54 rtas
= {IFLA_IFNAME
: ifname
,
57 IFLA_INFO_KIND
: 'vlan',
59 IFLA_VLAN_ID
: vlanid
,
63 token
= self
.request(RTM_NEWLINK
,
64 NLM_F_CREATE | NLM_F_REQUEST | NLM_F_ACK
, ifm
, rtas
)
65 self
.process_wait([token
])
67 def create_macvlan(self
, ifname
, link
, mode
='private'):
68 self
.logger
.info('rtnetlink: creating macvlan interface %s' %ifname
)
69 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
72 ifindex
= self
.get_ifindex(link
)
74 raise Exception('cannot determine ifindex for link %s (%s)'
77 ifm
= Ifinfomsg(AF_UNSPEC
)
78 rtas
= {IFLA_IFNAME
: ifname
,
81 IFLA_INFO_KIND
: 'macvlan',
83 IFLA_MACVLAN_MODE
: MACVLAN_MODE_PRIVATE
,
87 token
= self
.request(RTM_NEWLINK
, NLM_F_CREATE | NLM_F_REQUEST |
89 self
.process_wait([token
])
91 def link_set(self
, ifname
, state
):
93 self
.logger
.info('rtnetlink: setting link %s %s' %(ifname
, state
))
94 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
102 ifm
= Ifinfomsg(AF_UNSPEC
, ifi_change
=IFF_UP
, ifi_flags
=flags
)
103 rtas
= {IFLA_IFNAME
: ifname
}
105 token
= self
.request(RTM_NEWLINK
, NLM_F_REQUEST | NLM_F_ACK
, ifm
, rtas
)
106 self
.process_wait([token
])
108 def link_set_hwaddress(self
, ifname
, hwaddress
):
110 self
.logger
.info('rtnetlink: setting link hwaddress %s %s' %(ifname
, hwaddress
))
111 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
115 ifm
= Ifinfomsg(AF_UNSPEC
, ifi_change
=IFF_UP
)
116 rtas
= {IFLA_IFNAME
: ifname
,
117 IFLA_ADDRESS
: str(bytearray([int(a
,16) for a
in hwaddress
.split(':')]))}
119 self
.logger
.info(rtas
)
121 token
= self
.request(RTM_NEWLINK
, NLM_F_REQUEST | NLM_F_ACK
, ifm
, rtas
)
122 self
.process_wait([token
])
124 def addr_add(self
, ifname
, address
, broadcast
=None, peer
=None, scope
=None,
125 preferred_lifetime
=None):
126 self
.logger
.info('rtnetlink: setting address')
127 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
131 ifindex
= self
.get_ifindex(link
)
133 raise Exception('cannot determine ifindex for link %s (%s)'
135 ifa_scope
= RT_SCOPE_
137 if scope
== "universe":
138 ifa_scope
= RT_SCOPE_UNIVERSE
139 elif scope
== "site":
140 ifa_scope
= RT_SCOPE_SITE
141 elif scope
== "link":
142 ifa_scope
= RT_SCOPE_LINK
143 elif scope
== "host":
144 ifa_scope
= RT_SCOPE_HOST
145 elif scope
== "nowhere":
146 ifa_scope
= RT_SCOPE_NOWHERE
147 rtas
= {IFLA_ADDRESS
: ifname
}
149 ifa
= Ifaddrmsg(AF_UNSPEC
, ifa_scope
=ifa_scope
, ifa_index
=ifindex
)
151 token
= self
.request(RTM_NEWADDR
, NLM_F_REQUEST | NLM_F_ACK
, ifa
, rtas
)
152 self
.process_wait([token
])
154 def link_set_many(self
, ifname
, ifattrs
):
155 _ifattr_to_rta_map
= {'dev' : IFLA_NAME
,
156 'address' : IFLA_ADDRESS
,
157 'broadcast' : IFLA_BROADCAST
,
159 'master' : IFLA_MASTER
}
163 self
.logger
.info('rtnetlink: setting link %s %s' %(ifname
, state
))
164 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
168 state
= ifattrs
.get('state')
171 elif state
== 'down':
177 ifm
= Ifinfomsg(AF_UNSPEC
, ifi_change
=IFF_UP
, ifi_flags
=flags
)
179 ifm
= Ifinfomsg(AF_UNSPEC
)
181 for attr
, attrval
in ifattrs
.items():
182 rta_attr
= _ifattr_to_rta_map
.get(attr
)
184 if attr
== 'hwaddress':
185 rtas
[rta_attr
] = str(bytearray([int(a
,16) for a
in attrval
.split(':')]))
187 rtas
[rta_attr
] = attrval
189 token
= self
.request(RTM_NEWLINK
, NLM_F_REQUEST | NLM_F_ACK
, ifm
, rtas
)
190 self
.process_wait([token
])
192 def bridge_vlan(self
, add
=True, vid
=None, dev
=None, pvid
=False,
193 untagged
=False, master
=True):
196 if not vid
or not dev
:
198 self
.logger
.info('rtnetlink: bridge vlan add vid %s %s %s dev %s %s'
199 %(vid
, 'untagged' if untagged
else '',
200 'pvid' if pvid
else '', dev
,
201 'self' if self
else ''))
202 if ifupdownmain
.ifupdownFlags
.DRYRUN
:
205 ifindex
= self
.get_ifindex(dev
)
207 raise Exception('cannot determine ifindex for dev %s (%s)'
210 flags
= BRIDGE_FLAGS_SELF
213 vflags
= BRIDGE_VLAN_INFO_PVID
214 vflags |
= BRIDGE_VLAN_INFO_UNTAGGED
216 vflags |
= BRIDGE_VLAN_INFO_UNTAGGED
218 ifm
= Ifinfomsg(AF_BRIDGE
, ifi_index
=ifindex
)
219 rtas
= {IFLA_AF_SPEC
: {
220 IFLA_BRIDGE_FLAGS
: flags
,
221 IFLA_BRIDGE_VLAN_INFO
: BridgeVlanInfo(vflags
, int(vid
), int(vid
))
225 token
= self
.request(RTM_SETLINK
,
226 NLM_F_REQUEST | NLM_F_ACK
, ifm
, rtas
)
228 token
= self
.request(RTM_DELLINK
,
229 NLM_F_REQUEST | NLM_F_ACK
, ifm
, rtas
)
230 self
.process_wait([token
])
232 def bridge_vlan_many(self
, add
=True, vids
=[], dev
=None, pvid
=False,
233 untagged
=False, master
=True):
235 self
.bridge_vlan_add(add
, v
, dev
, ispvid
, isuntagged
, master
)
237 rtnl_api
= rtnetlinkApi(os
.getpid())