backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / zebra / db / interface.py
1 # Copyright (C) 2017 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 from __future__ import absolute_import
17
18 import logging
19
20 from sqlalchemy import Column
21 from sqlalchemy import Integer
22 from sqlalchemy import String
23
24 from ryu.lib import netdevice
25 from ryu.lib import ip
26 from ryu.lib.packet import zebra
27
28 from . import base
29
30
31 LOG = logging.getLogger(__name__)
32
33 # Default value for ethernet interface
34 DEFAULT_ETH_FLAGS = (
35     netdevice.IFF_UP
36     | netdevice.IFF_BROADCAST
37     | netdevice.IFF_RUNNING
38     | netdevice.IFF_MULTICAST)
39 DEFAULT_ETH_MTU = 1500
40
41
42 class Interface(base.Base):
43     """
44     Interface table for Zebra protocol service.
45
46     The default value for each fields suppose "Loopback" interface.
47
48     ``ifindex``: Number of index.
49
50     ``ifname``: Name of this interface.
51
52     ``status``: A combination of flags
53     "ryu.lib.packet.zebra.ZEBRA_INTERFACE_*".
54     The default value shows "active" and "link-detect".
55
56     ``flags``: A combination of flags "ryu.lib.netdevice.IFF_*".
57     The default value show "up", "loopback" and "running".
58
59     ``metric``: Metric of this interface.
60
61     ``ifmtu``: IPv4 MTU of this interface.
62
63     ``ifmtu6``: IPv6 MTU of this interface.
64
65     ``bandwidth``: Bandwidth of this interface.
66
67     ``ll_type``: Link Layer Type.
68     One of "ryu.lib.packet.zebra.ZEBRA_LLT_*" types.
69
70     ``hw_addr``: Hardware address of this interface (mostly, MAC address).
71
72     ``inet``: List of IPv4 addresses separated by a comma.
73     (e.g., "192.168.1.100/24,192.168.2.100/24)".
74
75     ``inet6``: List of IPv6 addresses separated by a comma.
76     """
77     __tablename__ = 'interface'
78
79     ifindex = Column(Integer, primary_key=True)
80     ifname = Column(String, default="lo")
81     status = Column(
82         Integer,
83         default=(
84             zebra.ZEBRA_INTERFACE_ACTIVE
85             | zebra.ZEBRA_INTERFACE_LINKDETECTION))
86     flags = Column(
87         Integer,
88         default=(
89             netdevice.IFF_UP
90             | netdevice.IFF_LOOPBACK
91             | netdevice.IFF_RUNNING))
92     metric = Column(Integer, default=1)
93     ifmtu = Column(Integer, default=0x10000)
94     ifmtu6 = Column(Integer, default=0x10000)
95     bandwidth = Column(Integer, default=0)
96     ll_type = Column(Integer, default=zebra.ZEBRA_LLT_ETHER)
97     hw_addr = Column(String, default='00:00:00:00:00:00')
98     # Note: Only the PostgreSQL backend has support sqlalchemy.ARRAY,
99     # we use the comma separated string as array instead.
100     inet = Column(String, default='')
101     inet6 = Column(String, default='')
102
103
104 @base.sql_function
105 def ip_link_show(session, **kwargs):
106     """
107     Returns a first interface record matching the given filtering rules.
108
109     The arguments for "kwargs" is the same with Interface class.
110
111     :param session: Session instance connecting to database.
112     :param kwargs: Filtering rules to query.
113     :return: An instance of Interface record.
114     """
115     return session.query(Interface).filter_by(**kwargs).first()
116
117
118 @base.sql_function
119 def ip_link_show_all(session, **kwargs):
120     """
121     Returns all interface records matching the given filtering rules.
122
123     The arguments for "kwargs" is the same with Interface class.
124
125     :param session: Session instance connecting to database.
126     :param kwargs: Filtering rules to query.
127     :return: A list of Interface records.
128     """
129     return session.query(Interface).filter_by(**kwargs).all()
130
131
132 @base.sql_function
133 def ip_link_add(session, name, type_='loopback', lladdr='00:00:00:00:00:00'):
134     """
135     Adds an interface record into Zebra protocol service database.
136
137     The arguments are similar to "ip link add" command of iproute2.
138
139     :param session: Session instance connecting to database.
140     :param name: Name of interface.
141     :param type_: Type of interface. 'loopback' or 'ethernet'.
142     :param lladdr: Link layer address. Mostly MAC address.
143     :return: Instance of added record or already existing record.
144     """
145     intf = ip_link_show(session, ifname=name)
146     if intf:
147         LOG.debug('Interface "%s" already exists: %s', intf.ifname, intf)
148         return intf
149
150     if type_ == 'ethernet':
151         intf = Interface(
152             ifname=name,
153             flags=DEFAULT_ETH_FLAGS,
154             ifmtu=DEFAULT_ETH_MTU,
155             ifmtu6=DEFAULT_ETH_MTU,
156             hw_addr=lladdr)
157     else:  # type_ == 'loopback':
158         intf = Interface(
159             ifname=name,
160             inet='127.0.0.1/8',
161             inet6='::1/128')
162
163     session.add(intf)
164
165     return intf
166
167
168 @base.sql_function
169 def ip_link_delete(session, name):
170     """
171     Deletes an interface record from Zebra protocol service database.
172
173     The arguments are similar to "ip link delete" command of iproute2.
174
175     :param session: Session instance connecting to database.
176     :param name: Name of interface.
177     :return: Name of interface which was deleted. None if failed.
178     """
179     intf = ip_link_show(session, ifname=name)
180     if not intf:
181         LOG.debug('Interface "%s" does not exist', name)
182         return None
183
184     session.delete(intf)
185
186     return name
187
188
189 # Currently, functions corresponding to "ip link show" and "ip address show"
190 # have the same implementation.
191 ip_address_show = ip_link_show
192 ip_address_show_all = ip_link_show_all
193
194
195 @base.sql_function
196 def ip_address_add(session, ifname, ifaddr):
197     """
198     Adds an IP address to interface record identified with the given "ifname".
199
200     The arguments are similar to "ip address add" command of iproute2.
201
202     :param session: Session instance connecting to database.
203     :param ifname: Name of interface.
204     :param ifaddr: IPv4 or IPv6 address.
205     :return: Instance of record or "None" if failed.
206     """
207     def _append_inet_addr(intf_inet, addr):
208         addr_list = intf_inet.split(',')
209         if addr in addr_list:
210             LOG.debug(
211                 'Interface "%s" has already "ifaddr": %s',
212                 intf.ifname, addr)
213             return intf_inet
214         else:
215             addr_list.append(addr)
216             return ','.join(addr_list)
217
218     intf = ip_link_show(session, ifname=ifname)
219     if not intf:
220         LOG.debug('Interface "%s" does not exist', ifname)
221         return None
222
223     if ip.valid_ipv4(ifaddr):
224         intf.inet = _append_inet_addr(intf.inet, ifaddr)
225     elif ip.valid_ipv6(ifaddr):
226         intf.inet6 = _append_inet_addr(intf.inet6, ifaddr)
227     else:
228         LOG.debug('Invalid IP address for "ifaddr": %s', ifaddr)
229         return None
230
231     return intf
232
233
234 @base.sql_function
235 def ip_address_delete(session, ifname, ifaddr):
236     """
237     Deletes an IP address from interface record identified with the given
238     "ifname".
239
240     The arguments are similar to "ip address delete" command of iproute2.
241
242     :param session: Session instance connecting to database.
243     :param ifname: Name of interface.
244     :param ifaddr: IPv4 or IPv6 address.
245     :return: Instance of record or "None" if failed.
246     """
247     def _remove_inet_addr(intf_inet, addr):
248         addr_list = intf_inet.split(',')
249         if addr not in addr_list:
250             LOG.debug(
251                 'Interface "%s" does not have "ifaddr": %s',
252                 intf.ifname, addr)
253             return intf_inet
254         else:
255             addr_list.remove(addr)
256             return ','.join(addr_list)
257
258     intf = ip_link_show(session, ifname=ifname)
259     if not intf:
260         LOG.debug('Interface "%s" does not exist', ifname)
261         return None
262
263     if ip.valid_ipv4(ifaddr):
264         intf.inet = _remove_inet_addr(intf.inet, ifaddr)
265     elif ip.valid_ipv6(ifaddr):
266         intf.inet6 = _remove_inet_addr(intf.inet6, ifaddr)
267     else:
268         LOG.debug('Invalid IP address for "ifaddr": %s', ifaddr)
269         return None
270
271     return intf