Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright (C) 2014 Tom Gundersen
7 : Copyright (C) 2014 Susant Sahani
8 :
9 : systemd is free software; you can redistribute it and/or modify it
10 : under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation; either version 2.1 of the License, or
12 : (at your option) any later version.
13 :
14 : systemd is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 : ***/
22 :
23 : #include "async.h"
24 : #include "lldp-port.h"
25 : #include "lldp-network.h"
26 :
27 0 : int lldp_port_start(lldp_port *p) {
28 : int r;
29 :
30 0 : assert_return(p, -EINVAL);
31 :
32 0 : r = lldp_network_bind_raw_socket(p->ifindex);
33 0 : if (r < 0)
34 0 : return r;
35 :
36 0 : p->rawfd = r;
37 :
38 0 : r = sd_event_add_io(p->event, &p->lldp_port_rx,
39 : p->rawfd, EPOLLIN, lldp_receive_packet, p);
40 0 : if (r < 0) {
41 0 : log_debug("Failed to allocate event source: %s", strerror(-r));
42 0 : return r;
43 : }
44 :
45 0 : r = sd_event_source_set_priority(p->lldp_port_rx, p->event_priority);
46 0 : if (r < 0) {
47 0 : log_debug("Failed to set event priority: %s", strerror(-r));
48 0 : goto fail;
49 : }
50 :
51 0 : r = sd_event_source_set_description(p->lldp_port_rx, "lldp-port-rx");
52 0 : if (r < 0) {
53 0 : log_debug("Failed to set event name: %s", strerror(-r));
54 0 : goto fail;
55 : }
56 :
57 0 : return 0;
58 :
59 : fail:
60 0 : lldp_port_stop(p);
61 :
62 0 : return r;
63 : }
64 :
65 0 : int lldp_port_stop(lldp_port *p) {
66 :
67 0 : assert_return(p, -EINVAL);
68 :
69 0 : p->rawfd = asynchronous_close(p->rawfd);
70 0 : p->lldp_port_rx = sd_event_source_unref(p->lldp_port_rx);
71 :
72 0 : return 0;
73 : }
74 :
75 0 : void lldp_port_free(lldp_port *p) {
76 0 : if (!p)
77 0 : return;
78 :
79 0 : lldp_port_stop(p);
80 :
81 0 : free(p->ifname);
82 0 : free(p);
83 : }
84 :
85 0 : int lldp_port_new(int ifindex,
86 : const char *ifname,
87 : const struct ether_addr *addr,
88 : void *userdata,
89 : lldp_port **ret) {
90 0 : _cleanup_free_ lldp_port *p = NULL;
91 :
92 0 : assert_return(ifindex, -EINVAL);
93 0 : assert_return(ifname, -EINVAL);
94 0 : assert_return(addr, -EINVAL);
95 :
96 0 : p = new0(lldp_port, 1);
97 0 : if (!p)
98 0 : return -ENOMEM;
99 :
100 0 : p->rawfd = -1;
101 0 : p->ifindex = ifindex;
102 :
103 0 : p->ifname = strdup(ifname);
104 0 : if (!p->ifname)
105 0 : return -ENOMEM;
106 :
107 0 : memcpy(&p->mac, addr, ETH_ALEN);
108 :
109 0 : p->userdata = userdata;
110 :
111 0 : *ret = p;
112 :
113 0 : p = NULL;
114 :
115 0 : return 0;
116 : }
|