-
- ofpbuf_init(&request, 0);
-
- nl_flags = NLM_F_REQUEST;
- if (create) {
- nl_flags |= NLM_F_CREATE|NLM_F_EXCL;
- }
-
- /* We over-reserve space, because we do some pointer arithmetic
- * and don't want the buffer address shifting under us. */
- nl_msg_put_nlmsghdr(&request, gre_descriptors.nl_sock, 2048, RTM_NEWLINK,
- nl_flags);
-
- memset(&ifinfomsg, 0, sizeof ifinfomsg);
- ifinfomsg.ifi_family = AF_UNSPEC;
- nl_msg_put(&request, &ifinfomsg, sizeof ifinfomsg);
-
- linkinfo_hdr = ofpbuf_tail(&request);
- nl_msg_put_unspec(&request, IFLA_LINKINFO, NULL, 0);
-
- nl_msg_put_unspec(&request, IFLA_INFO_KIND, "gretap", 6);
-
- info_data_hdr = ofpbuf_tail(&request);
- nl_msg_put_unspec(&request, IFLA_INFO_DATA, NULL, 0);
-
- /* Set flags */
- if (config->have_in_key) {
- iflags |= GRE_KEY;
- }
- if (config->have_out_key) {
- oflags |= GRE_KEY;
- }
-
- if (config->in_csum) {
- iflags |= GRE_CSUM;
- }
- if (config->out_csum) {
- oflags |= GRE_CSUM;
- }
-
- /* Add options */
- nl_msg_put_u32(&request, IFLA_GRE_IKEY, config->in_key);
- nl_msg_put_u32(&request, IFLA_GRE_OKEY, config->out_key);
- nl_msg_put_u16(&request, IFLA_GRE_IFLAGS, iflags);
- nl_msg_put_u16(&request, IFLA_GRE_OFLAGS, oflags);
- nl_msg_put_u32(&request, IFLA_GRE_LOCAL, config->local_ip);
- nl_msg_put_u32(&request, IFLA_GRE_REMOTE, config->remote_ip);
- nl_msg_put_u8(&request, IFLA_GRE_PMTUDISC, pmtudisc);
- nl_msg_put_u8(&request, IFLA_GRE_TTL, 0);
- nl_msg_put_u8(&request, IFLA_GRE_TOS, 0);
-
- info_data_hdr->nla_len = (char *)ofpbuf_tail(&request)
- - (char *)info_data_hdr;
- linkinfo_hdr->nla_len = (char *)ofpbuf_tail(&request)
- - (char *)linkinfo_hdr;
-
- nl_msg_put_string(&request, IFLA_IFNAME, name);
-
- error = nl_sock_transact(gre_descriptors.nl_sock, &request, &reply);
- ofpbuf_uninit(&request);
- if (error) {
- VLOG_WARN("couldn't transact netlink socket: %s\n", strerror(error));
- goto error;
- }
- ofpbuf_delete(reply);
-
-error:
- return error;
-#endif