Coverage Report

Created: 2025-08-28 06:46

/src/systemd/src/network/netdev/ipoib.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include <linux/if_arp.h>
4
#include <linux/if_link.h>
5
6
#include "sd-netlink.h"
7
8
#include "conf-parser.h"
9
#include "ipoib.h"
10
#include "networkd-link.h"
11
#include "networkd-network.h"
12
#include "parse-util.h"
13
#include "string-table.h"
14
#include "string-util.h"
15
16
assert_cc((int) IP_OVER_INFINIBAND_MODE_DATAGRAM  == (int) IPOIB_MODE_DATAGRAM);
17
assert_cc((int) IP_OVER_INFINIBAND_MODE_CONNECTED == (int) IPOIB_MODE_CONNECTED);
18
19
53
static void netdev_ipoib_init(NetDev *netdev) {
20
53
        IPoIB *ipoib = IPOIB(netdev);
21
22
53
        ipoib->mode = _IP_OVER_INFINIBAND_MODE_INVALID;
23
53
        ipoib->umcast = -1;
24
53
}
25
26
0
static int netdev_ipoib_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
27
0
        assert(link);
28
0
        assert(m);
29
30
0
        IPoIB *ipoib = IPOIB(netdev);
31
0
        int r;
32
33
0
        if (ipoib->pkey > 0) {
34
0
                r = sd_netlink_message_append_u16(m, IFLA_IPOIB_PKEY, ipoib->pkey);
35
0
                if (r < 0)
36
0
                        return r;
37
0
        }
38
39
0
        if (ipoib->mode >= 0) {
40
0
                r = sd_netlink_message_append_u16(m, IFLA_IPOIB_MODE, ipoib->mode);
41
0
                if (r < 0)
42
0
                        return r;
43
0
        }
44
45
0
        if (ipoib->umcast >= 0) {
46
0
                r = sd_netlink_message_append_u16(m, IFLA_IPOIB_UMCAST, ipoib->umcast);
47
0
                if (r < 0)
48
0
                        return r;
49
0
        }
50
51
0
        return 0;
52
0
}
53
54
0
int ipoib_set_netlink_message(Link *link, sd_netlink_message *m) {
55
0
        int r;
56
57
0
        assert(link);
58
0
        assert(link->network);
59
0
        assert(m);
60
61
0
        r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
62
0
        if (r < 0)
63
0
                return r;
64
65
0
        r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, link->kind);
66
0
        if (r < 0)
67
0
                return r;
68
69
0
        if (link->network->ipoib_mode >= 0) {
70
0
                r = sd_netlink_message_append_u16(m, IFLA_IPOIB_MODE, link->network->ipoib_mode);
71
0
                if (r < 0)
72
0
                        return r;
73
0
        }
74
75
0
        if (link->network->ipoib_umcast >= 0) {
76
0
                r = sd_netlink_message_append_u16(m, IFLA_IPOIB_UMCAST, link->network->ipoib_umcast);
77
0
                if (r < 0)
78
0
                        return r;
79
0
        }
80
81
0
        r = sd_netlink_message_close_container(m);
82
0
        if (r < 0)
83
0
                return r;
84
85
0
        r = sd_netlink_message_close_container(m);
86
0
        if (r < 0)
87
0
                return r;
88
89
0
        return 0;
90
0
}
91
92
static const char * const ipoib_mode_table[_IP_OVER_INFINIBAND_MODE_MAX] = {
93
        [IP_OVER_INFINIBAND_MODE_DATAGRAM]  = "datagram",
94
        [IP_OVER_INFINIBAND_MODE_CONNECTED] = "connected",
95
};
96
97
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(ipoib_mode, IPoIBMode);
98
DEFINE_CONFIG_PARSE_ENUM(config_parse_ipoib_mode, ipoib_mode, IPoIBMode);
99
100
int config_parse_ipoib_pkey(
101
                const char *unit,
102
                const char *filename,
103
                unsigned line,
104
                const char *section,
105
                unsigned section_line,
106
                const char *lvalue,
107
                int ltype,
108
                const char *rvalue,
109
                void *data,
110
781
                void *userdata) {
111
112
781
        uint16_t u, *pkey = ASSERT_PTR(data);
113
781
        int r;
114
115
781
        assert(filename);
116
781
        assert(lvalue);
117
781
        assert(rvalue);
118
119
781
        if (isempty(rvalue)) {
120
194
                *pkey = 0; /* 0 means unset. */
121
194
                return 0;
122
194
        }
123
124
587
        r = safe_atou16(rvalue, &u);
125
587
        if (r < 0) {
126
194
                log_syntax(unit, LOG_WARNING, filename, line, r,
127
194
                           "Failed to parse IPoIB pkey '%s', ignoring assignment: %m",
128
194
                           rvalue);
129
194
                return 0;
130
194
        }
131
393
        if (IN_SET(u, 0, 0x8000)) {
132
194
                log_syntax(unit, LOG_WARNING, filename, line, 0,
133
194
                           "IPoIB pkey cannot be 0 nor 0x8000, ignoring assignment: %s",
134
194
                           rvalue);
135
194
                return 0;
136
194
        }
137
138
199
        *pkey = u;
139
199
        return 0;
140
393
}
141
142
const NetDevVTable ipoib_vtable = {
143
        .object_size = sizeof(IPoIB),
144
        .sections = NETDEV_COMMON_SECTIONS "IPoIB\0",
145
        .init = netdev_ipoib_init,
146
        .fill_message_create = netdev_ipoib_fill_message_create,
147
        .create_type = NETDEV_CREATE_STACKED,
148
        .iftype = ARPHRD_INFINIBAND,
149
        .generate_mac = true,
150
};