|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# Copyright (c) 2019 Red Hat, Inc.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# This file is part of nmstate
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# This program is free software: you can redistribute it and/or modify
|
|
Packit |
b9ca78 |
# it under the terms of the GNU Lesser General Public License as published by
|
|
Packit |
b9ca78 |
# the Free Software Foundation, either version 2.1 of the License, or
|
|
Packit |
b9ca78 |
# (at your option) any later version.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# This program is distributed in the hope that it will be useful,
|
|
Packit |
b9ca78 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
b9ca78 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
b9ca78 |
# GNU Lesser General Public License for more details.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
b9ca78 |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
import socket
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
from libnmstate import iplib
|
|
Packit |
b9ca78 |
from libnmstate.error import NmstateValueError
|
|
Packit |
b9ca78 |
from libnmstate.schema import Interface
|
|
Packit |
b9ca78 |
from libnmstate.schema import Route
|
|
Packit |
b9ca78 |
from libnmstate.schema import RouteRule
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
from .common import GLib
|
|
Packit |
b9ca78 |
from .common import NM
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
IPV4_DEFAULT_GATEWAY_DESTINATION = "0.0.0.0/0"
|
|
Packit |
b9ca78 |
IPV6_DEFAULT_GATEWAY_DESTINATION = "::/0"
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
# NM require route rule priority been set explicitly, use 30,000 when
|
|
Packit |
b9ca78 |
# desire state instruct to use USE_DEFAULT_PRIORITY
|
|
Packit |
b9ca78 |
ROUTE_RULE_DEFAULT_PRIORIRY = 30000
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
def add_routes(setting_ip, routes):
|
|
Packit |
b9ca78 |
for route in routes:
|
|
Packit Service |
293802 |
_add_specfic_route(setting_ip, route)
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
def _add_specfic_route(setting_ip, route):
|
|
Packit |
b9ca78 |
destination, prefix_len = route[Route.DESTINATION].split("/")
|
|
Packit |
b9ca78 |
prefix_len = int(prefix_len)
|
|
Packit |
b9ca78 |
if iplib.is_ipv6_address(destination):
|
|
Packit |
b9ca78 |
family = socket.AF_INET6
|
|
Packit |
b9ca78 |
else:
|
|
Packit |
b9ca78 |
family = socket.AF_INET
|
|
Packit |
b9ca78 |
metric = route.get(Route.METRIC, Route.USE_DEFAULT_METRIC)
|
|
Packit Service |
08838e |
if route[Route.NEXT_HOP_ADDRESS]:
|
|
Packit Service |
08838e |
next_hop = route[Route.NEXT_HOP_ADDRESS]
|
|
Packit Service |
08838e |
else:
|
|
Packit Service |
08838e |
# NM.IPRoute.new() need None instead of ""
|
|
Packit Service |
08838e |
next_hop = None
|
|
Packit |
b9ca78 |
ip_route = NM.IPRoute.new(
|
|
Packit |
b9ca78 |
family, destination, prefix_len, next_hop, metric
|
|
Packit |
b9ca78 |
)
|
|
Packit |
b9ca78 |
table_id = route.get(Route.TABLE_ID, Route.USE_DEFAULT_ROUTE_TABLE)
|
|
Packit |
b9ca78 |
ip_route.set_attribute(
|
|
Packit Service |
293802 |
NM.IP_ROUTE_ATTRIBUTE_TABLE, GLib.Variant.new_uint32(table_id)
|
|
Packit |
b9ca78 |
)
|
|
Packit |
b9ca78 |
# Duplicate route entry will be ignored by libnm.
|
|
Packit |
b9ca78 |
setting_ip.add_route(ip_route)
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
def get_static_gateway_iface(family, iface_routes):
|
|
Packit |
b9ca78 |
"""
|
|
Packit |
b9ca78 |
Return one interface with gateway for given IP family.
|
|
Packit |
b9ca78 |
Return None if not found.
|
|
Packit |
b9ca78 |
"""
|
|
Packit |
b9ca78 |
destination = (
|
|
Packit |
b9ca78 |
IPV6_DEFAULT_GATEWAY_DESTINATION
|
|
Packit |
b9ca78 |
if family == Interface.IPV6
|
|
Packit |
b9ca78 |
else IPV4_DEFAULT_GATEWAY_DESTINATION
|
|
Packit |
b9ca78 |
)
|
|
Packit |
b9ca78 |
for iface_name, routes in iface_routes.items():
|
|
Packit |
b9ca78 |
for route in routes:
|
|
Packit |
b9ca78 |
if route[Route.DESTINATION] == destination:
|
|
Packit |
b9ca78 |
return iface_name
|
|
Packit |
b9ca78 |
return None
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
def add_route_rules(setting_ip, family, rules):
|
|
Packit |
b9ca78 |
for rule in rules:
|
|
Packit |
b9ca78 |
setting_ip.add_routing_rule(_rule_info_to_nm_rule(rule, family))
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
def _rule_info_to_nm_rule(rule, family):
|
|
Packit |
b9ca78 |
nm_rule = NM.IPRoutingRule.new(family)
|
|
Packit |
b9ca78 |
ip_from = rule.get(RouteRule.IP_FROM)
|
|
Packit |
b9ca78 |
ip_to = rule.get(RouteRule.IP_TO)
|
|
Packit |
b9ca78 |
if not ip_from and not ip_to:
|
|
Packit |
b9ca78 |
raise NmstateValueError(
|
|
Packit |
b9ca78 |
f"Neither {RouteRule.IP_FROM} or {RouteRule.IP_TO} is defined"
|
|
Packit |
b9ca78 |
)
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
if ip_from:
|
|
Packit |
b9ca78 |
nm_rule.set_from(*iplib.ip_address_full_to_tuple(ip_from))
|
|
Packit |
b9ca78 |
if ip_to:
|
|
Packit |
b9ca78 |
nm_rule.set_to(*iplib.ip_address_full_to_tuple(ip_to))
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
priority = rule.get(RouteRule.PRIORITY)
|
|
Packit |
b9ca78 |
if priority and priority != RouteRule.USE_DEFAULT_PRIORITY:
|
|
Packit |
b9ca78 |
nm_rule.set_priority(priority)
|
|
Packit |
b9ca78 |
else:
|
|
Packit |
b9ca78 |
nm_rule.set_priority(ROUTE_RULE_DEFAULT_PRIORIRY)
|
|
Packit |
b9ca78 |
table = rule.get(RouteRule.ROUTE_TABLE)
|
|
Packit |
b9ca78 |
if table and table != RouteRule.USE_DEFAULT_ROUTE_TABLE:
|
|
Packit |
b9ca78 |
nm_rule.set_table(table)
|
|
Packit |
b9ca78 |
else:
|
|
Packit |
b9ca78 |
nm_rule.set_table(iplib.KERNEL_MAIN_ROUTE_TABLE_ID)
|
|
Packit |
b9ca78 |
return nm_rule
|