Blame libnmstate/nm/route.py

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