backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / zebra / db / route.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 import socket
20
21 from sqlalchemy import Column
22 from sqlalchemy import Boolean
23 from sqlalchemy import Integer
24 from sqlalchemy import String
25
26 from ryu.lib import ip
27 from ryu.lib.packet import safi as packet_safi
28 from ryu.lib.packet import zebra
29
30 from . import base
31 from . import interface
32
33
34 LOG = logging.getLogger(__name__)
35
36
37 class Route(base.Base):
38     """
39     Route table (like routing table) for Zebra protocol service.
40
41     ``id``: (Primary Key) ID of this route.
42
43     ``family``: Address Family, not AFI (Address Family Identifiers).
44     Mostly, "socket.AF_INET" or "socket.AF_INET6".
45
46     ``safi``: Subsequent Address Family Identifiers.
47
48     ``destination``: Destination prefix of this route.
49
50     ``gateway``: Next hop address of this route.
51     The default is "" (empty string).
52
53     ``ifindex``: Index of interface to forward packets.
54
55     ``source``: Source IP address of this route, which should be an
56      address assigned to the local interface.
57
58     ``route_type``: Route Type of this route.
59     This type shows which daemon (or kernel) generated this route.
60
61     ``is_selected``: Whether this route is selected for "destination".
62     """
63     __tablename__ = 'route'
64
65     id = Column(Integer, primary_key=True)
66     family = Column(Integer, default=socket.AF_INET)
67     safi = Column(Integer, default=packet_safi.UNICAST)
68     destination = Column(String, default='0.0.0.0/0')
69     gateway = Column(String, default='')
70     ifindex = Column(Integer, default=0)
71     source = Column(String, default='')
72     route_type = Column(Integer, default=zebra.ZEBRA_ROUTE_KERNEL)
73     is_selected = Column(Boolean, default=False)
74
75
76 @base.sql_function
77 def ip_route_show(session, destination, device, **kwargs):
78     """
79     Returns a selected route record matching the given filtering rules.
80
81     The arguments are similar to "ip route showdump" command of iproute2.
82
83     :param session: Session instance connecting to database.
84     :param destination: Destination prefix.
85     :param device: Source device.
86     :param kwargs: Filtering rules to query.
87     :return: Instance of route record or "None" if failed.
88     """
89     intf = interface.ip_link_show(session, ifname=device)
90     if not intf:
91         LOG.debug('Interface "%s" does not exist', device)
92         return None
93
94     return session.query(Route).filter_by(
95         destination=destination, ifindex=intf.ifindex, **kwargs).first()
96
97
98 @base.sql_function
99 def ip_route_show_all(session, **kwargs):
100     """
101     Returns a selected route record matching the given filtering rules.
102
103     The arguments are similar to "ip route showdump" command of iproute2.
104
105     If "is_selected=True", disables the existing selected route for the
106     given destination.
107
108     :param session: Session instance connecting to database.
109     :param kwargs: Filtering rules to query.
110     :return: A list of route records.
111     """
112     return session.query(Route).filter_by(**kwargs).all()
113
114
115 @base.sql_function
116 def ip_route_add(session, destination, device=None, gateway='', source='',
117                  ifindex=0, route_type=zebra.ZEBRA_ROUTE_KERNEL,
118                  is_selected=True):
119     """
120     Adds a route record into Zebra protocol service database.
121
122     The arguments are similar to "ip route add" command of iproute2.
123
124     If "is_selected=True", disables the existing selected route for the
125     given destination.
126
127     :param session: Session instance connecting to database.
128     :param destination: Destination prefix.
129     :param device: Source device.
130     :param gateway: Gateway IP address.
131     :param source: Source IP address.
132     :param ifindex: Index of source device.
133     :param route_type: Route type of daemon (or kernel).
134     :param is_selected: If select the given route as "in use" or not.
135     :return: Instance of record or "None" if failed.
136     """
137     if device:
138         intf = interface.ip_link_show(session, ifname=device)
139         if not intf:
140             LOG.debug('Interface "%s" does not exist', device)
141             return None
142         ifindex = ifindex or intf.ifindex
143
144         route = ip_route_show(session, destination=destination, device=device)
145         if route:
146             LOG.debug(
147                 'Route to "%s" already exists on "%s" device',
148                 destination, device)
149             return route
150
151     dest_addr, dest_prefix_num = destination.split('/')
152     dest_prefix_num = int(dest_prefix_num)
153     if ip.valid_ipv4(dest_addr) and 0 <= dest_prefix_num <= 32:
154         family = socket.AF_INET
155     elif ip.valid_ipv6(dest_addr) and 0 <= dest_prefix_num <= 128:
156         family = socket.AF_INET6
157     else:
158         LOG.debug('Invalid IP address for "prefix": %s', destination)
159         return None
160     safi = packet_safi.UNICAST
161
162     if is_selected:
163         old_routes = ip_route_show_all(
164             session, destination=destination, is_selected=True)
165         for old_route in old_routes:
166             if old_route:
167                 LOG.debug('Set existing route to unselected: %s', old_route)
168                 old_route.is_selected = False
169
170     new_route = Route(
171         family=family,
172         safi=safi,
173         destination=destination,
174         gateway=gateway,
175         ifindex=ifindex,
176         source=source,
177         route_type=route_type,
178         is_selected=is_selected)
179
180     session.add(new_route)
181
182     return new_route
183
184
185 @base.sql_function
186 def ip_route_delete(session, destination, **kwargs):
187     """
188     Deletes route record(s) from Zebra protocol service database.
189
190     The arguments are similar to "ip route delete" command of iproute2.
191
192     :param session: Session instance connecting to database.
193     :param destination: Destination prefix.
194     :param kwargs: Filtering rules to query.
195     :return: Records which are deleted.
196     """
197     routes = ip_route_show_all(session, destination=destination, **kwargs)
198     for route in routes:
199         session.delete(route)
200
201     return routes