1 /*
2 * virebtables.c: Helper APIs for managing ebtables
3 *
4 * Copyright (C) 2007-2014 Red Hat, Inc.
5 * Copyright (C) 2009 IBM Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23
24 #include "internal.h"
25 #include "virebtables.h"
26 #include "viralloc.h"
27 #include "virerror.h"
28 #include "virlog.h"
29 #include "virstring.h"
30 #include "virfirewall.h"
31
32 #define VIR_FROM_THIS VIR_FROM_NONE
33
34 VIR_LOG_INIT("util.ebtables");
35
36 struct _ebtablesContext
37 {
38 char *chain;
39 };
40
41 enum {
42 ADD = 0,
43 REMOVE,
44 };
45
46 /**
47 * ebtablesContextNew:
48 *
49 * Create a new ebtable context
50 *
51 * Returns a pointer to the new structure or NULL in case of error
52 */
53 ebtablesContext *
ebtablesContextNew(const char * driver)54 ebtablesContextNew(const char *driver)
55 {
56 ebtablesContext *ctx = NULL;
57
58 ctx = g_new0(ebtablesContext, 1);
59
60 ctx->chain = g_strdup_printf("libvirt_%s_FORWARD", driver);
61
62 return ctx;
63 }
64
65 /**
66 * ebtablesContextFree:
67 * @ctx: pointer to the EB table context
68 *
69 * Free the resources associated with an EB table context
70 */
71 void
ebtablesContextFree(ebtablesContext * ctx)72 ebtablesContextFree(ebtablesContext *ctx)
73 {
74 if (!ctx)
75 return;
76 g_free(ctx->chain);
77 g_free(ctx);
78 }
79
80
81 int
ebtablesAddForwardPolicyReject(ebtablesContext * ctx)82 ebtablesAddForwardPolicyReject(ebtablesContext *ctx)
83 {
84 g_autoptr(virFirewall) fw = virFirewallNew();
85
86 virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
87 virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
88 "--new-chain", ctx->chain,
89 NULL);
90 virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
91 "--insert", "FORWARD",
92 "--jump", ctx->chain, NULL);
93
94 virFirewallStartTransaction(fw, 0);
95 virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
96 "-P", ctx->chain, "DROP",
97 NULL);
98
99 return virFirewallApply(fw);
100 }
101
102
103 /*
104 * Allow all traffic destined to the bridge, with a valid network address
105 */
106 static int
ebtablesForwardAllowIn(ebtablesContext * ctx,const char * iface,const char * macaddr,int action)107 ebtablesForwardAllowIn(ebtablesContext *ctx,
108 const char *iface,
109 const char *macaddr,
110 int action)
111 {
112 g_autoptr(virFirewall) fw = virFirewallNew();
113
114 virFirewallStartTransaction(fw, 0);
115 virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
116 action == ADD ? "--insert" : "--delete",
117 ctx->chain,
118 "--in-interface", iface,
119 "--source", macaddr,
120 "--jump", "ACCEPT",
121 NULL);
122
123 return virFirewallApply(fw);
124 }
125
126 /**
127 * ebtablesAddForwardAllowIn:
128 * @ctx: pointer to the EB table context
129 * @iface: the output interface name
130 * @physdev: the physical input device or NULL
131 *
132 * Add rules to the EB table context to allow the traffic on
133 * @physdev device to be forwarded to interface @iface. This allows
134 * the inbound traffic on a bridge.
135 *
136 * Returns 0 in case of success or an error code otherwise
137 */
138 int
ebtablesAddForwardAllowIn(ebtablesContext * ctx,const char * iface,const virMacAddr * mac)139 ebtablesAddForwardAllowIn(ebtablesContext *ctx,
140 const char *iface,
141 const virMacAddr *mac)
142 {
143 char macaddr[VIR_MAC_STRING_BUFLEN];
144
145 virMacAddrFormat(mac, macaddr);
146 return ebtablesForwardAllowIn(ctx, iface, macaddr, ADD);
147 }
148
149 /**
150 * ebtablesRemoveForwardAllowIn:
151 * @ctx: pointer to the EB table context
152 * @iface: the output interface name
153 * @physdev: the physical input device or NULL
154 *
155 * Remove rules from the EB table context hence forbidding the traffic
156 * on the @physdev device to be forwarded to interface @iface. This
157 * stops the inbound traffic on a bridge.
158 *
159 * Returns 0 in case of success or an error code otherwise
160 */
161 int
ebtablesRemoveForwardAllowIn(ebtablesContext * ctx,const char * iface,const virMacAddr * mac)162 ebtablesRemoveForwardAllowIn(ebtablesContext *ctx,
163 const char *iface,
164 const virMacAddr *mac)
165 {
166 char macaddr[VIR_MAC_STRING_BUFLEN];
167
168 virMacAddrFormat(mac, macaddr);
169 return ebtablesForwardAllowIn(ctx, iface, macaddr, REMOVE);
170 }
171