#ifdef HAVE_NLA_NUL_STRING
[OVS_VPORT_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
[OVS_VPORT_ATTR_STATS] = { .len = sizeof(struct ovs_vport_stats) },
- [OVS_VPORT_ATTR_ADDRESS] = { .len = ETH_ALEN },
#else
[OVS_VPORT_ATTR_STATS] = { .minlen = sizeof(struct ovs_vport_stats) },
- [OVS_VPORT_ATTR_ADDRESS] = { .minlen = ETH_ALEN },
#endif
[OVS_VPORT_ATTR_PORT_NO] = { .type = NLA_U32 },
[OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
&vport_stats))
goto nla_put_failure;
- if (nla_put(skb, OVS_VPORT_ATTR_ADDRESS, ETH_ALEN,
- vport->ops->get_addr(vport)))
- goto nla_put_failure;
-
err = ovs_vport_get_options(vport, skb);
if (err == -EMSGSIZE)
goto error;
return ERR_PTR(-EINVAL);
}
-/* Called with RTNL lock. */
-static int change_vport(struct vport *vport,
- struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
-{
- int err = 0;
-
- if (a[OVS_VPORT_ATTR_STATS])
- ovs_vport_set_stats(vport, nla_data(a[OVS_VPORT_ATTR_STATS]));
-
- if (a[OVS_VPORT_ATTR_ADDRESS])
- err = ovs_vport_set_addr(vport, nla_data(a[OVS_VPORT_ATTR_ADDRESS]));
-
- return err;
-}
-
static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr **a = info->attrs;
if (IS_ERR(vport))
goto exit_unlock;
- err = change_vport(vport, a);
- if (!err) {
- reply = ovs_vport_cmd_build_info(vport, info->snd_portid,
- info->snd_seq,
- OVS_VPORT_CMD_NEW);
- if (IS_ERR(reply))
- err = PTR_ERR(reply);
- }
- if (err) {
+ if (a[OVS_VPORT_ATTR_STATS])
+ ovs_vport_set_stats(vport, nla_data(a[OVS_VPORT_ATTR_STATS]));
+
+ reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
+ OVS_VPORT_CMD_NEW);
+ if (IS_ERR(reply)) {
+ err = PTR_ERR(reply);
ovs_dp_detach_port(vport);
goto exit_unlock;
}
if (!err && a[OVS_VPORT_ATTR_OPTIONS])
err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
- if (!err)
- err = change_vport(vport, a);
- else
+ if (err)
goto exit_unlock;
- if (!err && a[OVS_VPORT_ATTR_UPCALL_PID])
+
+ if (a[OVS_VPORT_ATTR_STATS])
+ ovs_vport_set_stats(vport, nla_data(a[OVS_VPORT_ATTR_STATS]));
+
+ if (a[OVS_VPORT_ATTR_UPCALL_PID])
vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
reply = ovs_vport_cmd_build_info(vport, info->snd_portid,
goto error_free_vport;
}
- random_ether_addr(mutable->eth_addr);
-
get_random_bytes(&initial_frag_id, sizeof(int));
atomic_set(&tnl_vport->frag_id, initial_frag_id);
goto error;
}
- /* Copy fields whose values should be retained. */
mutable->seq = old_mutable->seq + 1;
- memcpy(mutable->eth_addr, old_mutable->eth_addr, ETH_ALEN);
/* Parse the others configured by userspace. */
err = tnl_set_config(ovs_dp_get_net(vport->dp), options, tnl_vport->tnl_ops,
call_rcu(&tnl_vport->rcu, free_port_rcu);
}
-int ovs_tnl_set_addr(struct vport *vport, const unsigned char *addr)
-{
- struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
- struct tnl_mutable_config *old_mutable, *mutable;
-
- old_mutable = rtnl_dereference(tnl_vport->mutable);
- mutable = kmemdup(old_mutable, sizeof(struct tnl_mutable_config), GFP_KERNEL);
- if (!mutable)
- return -ENOMEM;
-
- old_mutable->mlink = 0;
-
- memcpy(mutable->eth_addr, addr, ETH_ALEN);
- assign_config_rcu(vport, mutable);
-
- return 0;
-}
-
const char *ovs_tnl_get_name(const struct vport *vport)
{
const struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
return tnl_vport->name;
}
-const unsigned char *ovs_tnl_get_addr(const struct vport *vport)
-{
- const struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
- return rcu_dereference_rtnl(tnl_vport->mutable)->eth_addr;
-}
-
void ovs_tnl_free_linked_skbs(struct sk_buff *skb)
{
while (skb) {
* @rcu: RCU callback head for deferred destruction.
* @seq: Sequence number for distinguishing configuration versions.
* @tunnel_hlen: Tunnel header length.
- * @eth_addr: Source address for packets generated by tunnel itself
- * (e.g. ICMP fragmentation needed messages).
* @out_key: Key to use on output, 0 if this tunnel has no fixed output key.
* @flags: TNL_F_* flags.
* @tos: IPv4 TOS value to use for tunnel, 0 if no fixed TOS.
unsigned seq;
- unsigned char eth_addr[ETH_ALEN];
-
/* Configured via OVS_TUNNEL_ATTR_* attributes. */
__be64 out_key;
u32 flags;
int ovs_tnl_set_options(struct vport *, struct nlattr *);
int ovs_tnl_get_options(const struct vport *, struct sk_buff *);
-int ovs_tnl_set_addr(struct vport *vport, const unsigned char *addr);
const char *ovs_tnl_get_name(const struct vport *vport);
-const unsigned char *ovs_tnl_get_addr(const struct vport *vport);
int ovs_tnl_send(struct vport *vport, struct sk_buff *skb);
void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb);
.exit = capwap_exit,
.create = capwap_create,
.destroy = capwap_destroy,
- .set_addr = ovs_tnl_set_addr,
.get_name = ovs_tnl_get_name,
- .get_addr = ovs_tnl_get_addr,
.get_options = ovs_tnl_get_options,
.set_options = ovs_tnl_set_options,
.send = ovs_tnl_send,
.exit = gre_exit,
.create = gre_create_ft,
.destroy = ovs_tnl_destroy,
- .set_addr = ovs_tnl_set_addr,
.get_name = ovs_tnl_get_name,
- .get_addr = ovs_tnl_get_addr,
.get_options = ovs_tnl_get_options,
.set_options = ovs_tnl_set_options,
.send = ovs_tnl_send,
.exit = gre_exit,
.create = gre_create,
.destroy = ovs_tnl_destroy,
- .set_addr = ovs_tnl_set_addr,
.get_name = ovs_tnl_get_name,
- .get_addr = ovs_tnl_get_addr,
.get_options = ovs_tnl_get_options,
.set_options = ovs_tnl_set_options,
.send = ovs_tnl_send,
.exit = gre_exit,
.create = gre_create64,
.destroy = ovs_tnl_destroy,
- .set_addr = ovs_tnl_set_addr,
.get_name = ovs_tnl_get_name,
- .get_addr = ovs_tnl_get_addr,
.get_options = ovs_tnl_get_options,
.set_options = ovs_tnl_set_options,
.send = ovs_tnl_send,
.flags = VPORT_F_REQUIRED | VPORT_F_FLOW,
.create = internal_dev_create,
.destroy = internal_dev_destroy,
- .set_addr = ovs_netdev_set_addr,
.get_name = ovs_netdev_get_name,
- .get_addr = ovs_netdev_get_addr,
.get_ifindex = ovs_netdev_get_ifindex,
.send = internal_dev_recv,
};
call_rcu(&netdev_vport->rcu, free_port_rcu);
}
-int ovs_netdev_set_addr(struct vport *vport, const unsigned char *addr)
-{
- struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
- struct sockaddr sa;
-
- sa.sa_family = ARPHRD_ETHER;
- memcpy(sa.sa_data, addr, ETH_ALEN);
-
- return dev_set_mac_address(netdev_vport->dev, &sa);
-}
-
const char *ovs_netdev_get_name(const struct vport *vport)
{
const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
return netdev_vport->dev->name;
}
-const unsigned char *ovs_netdev_get_addr(const struct vport *vport)
-{
- const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
- return netdev_vport->dev->dev_addr;
-}
-
int ovs_netdev_get_ifindex(const struct vport *vport)
{
const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
.exit = netdev_exit,
.create = netdev_create,
.destroy = netdev_destroy,
- .set_addr = ovs_netdev_set_addr,
.get_name = ovs_netdev_get_name,
- .get_addr = ovs_netdev_get_addr,
.get_ifindex = ovs_netdev_get_ifindex,
.send = netdev_send,
};
return vport_priv(vport);
}
-int ovs_netdev_set_addr(struct vport *, const unsigned char *addr);
const char *ovs_netdev_get_name(const struct vport *);
-const unsigned char *ovs_netdev_get_addr(const struct vport *);
const char *ovs_netdev_get_config(const struct vport *);
int ovs_netdev_get_ifindex(const struct vport *);
struct rcu_head rcu;
char peer_name[IFNAMSIZ];
- unsigned char eth_addr[ETH_ALEN];
};
struct patch_vport {
if (err)
goto error_free_patchconf;
- random_ether_addr(patchconf->eth_addr);
-
rcu_assign_pointer(patch_vport->patchconf, patchconf);
peer_name = patchconf->peer_name;
}
}
-static int patch_set_addr(struct vport *vport, const unsigned char *addr)
-{
- struct patch_vport *patch_vport = patch_vport_priv(vport);
- struct patch_config *patchconf;
-
- patchconf = kmemdup(rtnl_dereference(patch_vport->patchconf),
- sizeof(struct patch_config), GFP_KERNEL);
- if (!patchconf)
- return -ENOMEM;
-
- memcpy(patchconf->eth_addr, addr, ETH_ALEN);
- assign_config_rcu(vport, patchconf);
-
- return 0;
-}
-
-
static const char *patch_get_name(const struct vport *vport)
{
const struct patch_vport *patch_vport = patch_vport_priv(vport);
return patch_vport->name;
}
-static const unsigned char *patch_get_addr(const struct vport *vport)
-{
- const struct patch_vport *patch_vport = patch_vport_priv(vport);
- return rcu_dereference_rtnl(patch_vport->patchconf)->eth_addr;
-}
-
static int patch_get_options(const struct vport *vport, struct sk_buff *skb)
{
struct patch_vport *patch_vport = patch_vport_priv(vport);
.exit = patch_exit,
.create = patch_create,
.destroy = patch_destroy,
- .set_addr = patch_set_addr,
.get_name = patch_get_name,
- .get_addr = patch_get_addr,
.get_options = patch_get_options,
.set_options = patch_set_options,
.send = patch_send,
.flags = VPORT_F_TUN_ID,
.create = vxlan_tnl_create,
.destroy = vxlan_tnl_destroy,
- .set_addr = ovs_tnl_set_addr,
.get_name = ovs_tnl_get_name,
- .get_addr = ovs_tnl_get_addr,
.get_options = ovs_tnl_get_options,
.set_options = vxlan_set_options,
.send = ovs_tnl_send,
vport->ops->destroy(vport);
}
-/**
- * ovs_vport_set_addr - set device Ethernet address (for kernel callers)
- *
- * @vport: vport on which to set Ethernet address.
- * @addr: New address.
- *
- * Sets the Ethernet address of the given device. Some devices may not support
- * setting the Ethernet address, in which case the result will always be
- * -EOPNOTSUPP. RTNL lock must be held.
- */
-int ovs_vport_set_addr(struct vport *vport, const unsigned char *addr)
-{
- ASSERT_RTNL();
-
- if (!is_valid_ether_addr(addr))
- return -EADDRNOTAVAIL;
-
- if (vport->ops->set_addr)
- return vport->ops->set_addr(vport, addr);
- else
- return -EOPNOTSUPP;
-}
-
/**
* ovs_vport_set_stats - sets offset device stats
*
struct vport *ovs_vport_locate(struct net *net, const char *name);
-int ovs_vport_set_addr(struct vport *, const unsigned char *);
void ovs_vport_set_stats(struct vport *, struct ovs_vport_stats *);
void ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *);
* @get_options: Appends vport-specific attributes for the configuration of an
* existing vport to a &struct sk_buff. May be %NULL for a vport that does not
* have any configuration.
- * @set_addr: Set the device's MAC address. May be null if not supported.
* @get_name: Get the device's name.
- * @get_addr: Get the device's MAC address.
* @get_config: Get the device's configuration.
* @get_ifindex: Get the system interface index associated with the device.
* May be null if the device does not have an ifindex.
int (*set_options)(struct vport *, struct nlattr *);
int (*get_options)(const struct vport *, struct sk_buff *);
- int (*set_addr)(struct vport *, const unsigned char *);
-
/* Called with rcu_read_lock or RTNL lock. */
const char *(*get_name)(const struct vport *);
- const unsigned char *(*get_addr)(const struct vport *);
void (*get_config)(const struct vport *, void *);
int (*get_ifindex)(const struct vport *);
int (*send)(struct vport *, struct sk_buff *);
* this port. A value of zero indicates that upcalls should not be sent.
* @OVS_VPORT_ATTR_STATS: A &struct ovs_vport_stats giving statistics for
* packets sent or received through the vport.
- * @OVS_VPORT_ATTR_ADDRESS: A 6-byte Ethernet address for the vport.
*
* These attributes follow the &struct ovs_header within the Generic Netlink
* payload for %OVS_VPORT_* commands.
* %OVS_VPORT_ATTR_NAME attributes are required. %OVS_VPORT_ATTR_PORT_NO is
* optional; if not specified a free port number is automatically selected.
* Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type
- * of vport. %OVS_VPORT_ATTR_STATS and %OVS_VPORT_ATTR_ADDRESS are optional,
- * and other attributes are ignored.
+ * of vport. %OVS_VPORT_ATTR_STATS is optional and other attributes are
+ * ignored.
*
* For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to
* look up the vport to operate on; otherwise dp_idx from the &struct
OVS_VPORT_ATTR_OPTIONS, /* nested attributes, varies by vport type */
OVS_VPORT_ATTR_UPCALL_PID, /* u32 Netlink PID to receive upcalls */
OVS_VPORT_ATTR_STATS, /* struct ovs_vport_stats */
- OVS_VPORT_ATTR_ADDRESS = 100, /* hardware address */
__OVS_VPORT_ATTR_MAX
};
[OVS_VPORT_ATTR_UPCALL_PID] = { .type = NL_A_U32 },
[OVS_VPORT_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_vport_stats),
.optional = true },
- [OVS_VPORT_ATTR_ADDRESS] = { .type = NL_A_UNSPEC,
- .min_len = ETH_ADDR_LEN,
- .max_len = ETH_ADDR_LEN,
- .optional = true },
[OVS_VPORT_ATTR_OPTIONS] = { .type = NL_A_NESTED, .optional = true },
};
if (a[OVS_VPORT_ATTR_STATS]) {
vport->stats = nl_attr_get(a[OVS_VPORT_ATTR_STATS]);
}
- if (a[OVS_VPORT_ATTR_ADDRESS]) {
- vport->address = nl_attr_get(a[OVS_VPORT_ATTR_ADDRESS]);
- }
if (a[OVS_VPORT_ATTR_OPTIONS]) {
vport->options = nl_attr_get(a[OVS_VPORT_ATTR_OPTIONS]);
vport->options_len = nl_attr_get_size(a[OVS_VPORT_ATTR_OPTIONS]);
vport->stats, sizeof *vport->stats);
}
- if (vport->address) {
- nl_msg_put_unspec(buf, OVS_VPORT_ATTR_ADDRESS,
- vport->address, ETH_ADDR_LEN);
- }
-
if (vport->options) {
nl_msg_put_nested(buf, OVS_VPORT_ATTR_OPTIONS,
vport->options, vport->options_len);
const char *name; /* OVS_VPORT_ATTR_NAME. */
const uint32_t *upcall_pid; /* OVS_VPORT_ATTR_UPCALL_PID. */
const struct ovs_vport_stats *stats; /* OVS_VPORT_ATTR_STATS. */
- const uint8_t *address; /* OVS_VPORT_ATTR_ADDRESS. */
const struct nlattr *options; /* OVS_VPORT_ATTR_OPTIONS. */
size_t options_len;
};