get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/817705/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 817705,
    "url": "http://patchwork.ozlabs.org/api/patches/817705/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/f9d52b56b1c6fb8c671d23cfb0fc99bf36392239.1506114055.git.pabeni@redhat.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<f9d52b56b1c6fb8c671d23cfb0fc99bf36392239.1506114055.git.pabeni@redhat.com>",
    "list_archive_url": null,
    "date": "2017-09-22T21:06:32",
    "name": "[RFC,08/11] net: implement local route cache inside ifaddr",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "1de32b931176e10a10bb8f364364c58dbc461128",
    "submitter": {
        "id": 67312,
        "url": "http://patchwork.ozlabs.org/api/people/67312/?format=api",
        "name": "Paolo Abeni",
        "email": "pabeni@redhat.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/f9d52b56b1c6fb8c671d23cfb0fc99bf36392239.1506114055.git.pabeni@redhat.com/mbox/",
    "series": [
        {
            "id": 4709,
            "url": "http://patchwork.ozlabs.org/api/series/4709/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=4709",
            "date": "2017-09-22T21:06:24",
            "name": "udp: full early demux for unconnected sockets",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/4709/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/817705/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/817705/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
            "ext-mx07.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com",
            "ext-mx07.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=pabeni@redhat.com"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xzQz76qWpz9sP1\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat, 23 Sep 2017 07:07:15 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752752AbdIVVHO (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 22 Sep 2017 17:07:14 -0400",
            "from mx1.redhat.com ([209.132.183.28]:46576 \"EHLO mx1.redhat.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1752747AbdIVVHM (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tFri, 22 Sep 2017 17:07:12 -0400",
            "from smtp.corp.redhat.com\n\t(int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id AEF8FC098D0D;\n\tFri, 22 Sep 2017 21:07:12 +0000 (UTC)",
            "from dhcppc0.redhat.com (ovpn-116-39.ams2.redhat.com\n\t[10.36.116.39])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id ED2D4669E4;\n\tFri, 22 Sep 2017 21:07:10 +0000 (UTC)"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com AEF8FC098D0D",
        "From": "Paolo Abeni <pabeni@redhat.com>",
        "To": "netdev@vger.kernel.org",
        "Cc": "\"David S. Miller\" <davem@davemloft.net>,\n\tPablo Neira Ayuso <pablo@netfilter.org>, Florian Westphal <fw@strlen.de>,\n\tEric Dumazet <edumazet@google.com>,\n\tHannes Frederic Sowa <hannes@stressinduktion.org>",
        "Subject": "[RFC PATCH 08/11] net: implement local route cache inside ifaddr",
        "Date": "Fri, 22 Sep 2017 23:06:32 +0200",
        "Message-Id": "<f9d52b56b1c6fb8c671d23cfb0fc99bf36392239.1506114055.git.pabeni@redhat.com>",
        "In-Reply-To": "<cover.1506114055.git.pabeni@redhat.com>",
        "References": "<cover.1506114055.git.pabeni@redhat.com>",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.15",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.31]);\n\tFri, 22 Sep 2017 21:07:12 +0000 (UTC)",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "add storage and helpers to associate an ipv{4,6} address\nwith the local route to self. This will be used by a\nlater patch to implement early demux for unconnected UDP\nsockets.\n\nThe caches are filled on address creation, with DST_OBSOLETE_NONE.\nIpv6 cache are explicitly clearered and refreshed on underlaying\ndevice down/up events.\n\nThe above schema is simpler than refreshing the cache every\ntime the dst expires under the default obsolete schema.\n\nSigned-off-by: Paolo Abeni <pabeni@redhat.com>\n---\n include/linux/inetdevice.h |  4 ++++\n include/net/addrconf.h     |  3 +++\n include/net/if_inet6.h     |  4 ++++\n net/ipv4/devinet.c         | 29 ++++++++++++++++++++++++++++-\n net/ipv6/addrconf.c        | 44 ++++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 83 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h\nindex 751d051f0bc7..c29982f178bb 100644\n--- a/include/linux/inetdevice.h\n+++ b/include/linux/inetdevice.h\n@@ -130,6 +130,8 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)\n #define IN_DEV_ARP_IGNORE(in_dev)\tIN_DEV_MAXCONF((in_dev), ARP_IGNORE)\n #define IN_DEV_ARP_NOTIFY(in_dev)\tIN_DEV_MAXCONF((in_dev), ARP_NOTIFY)\n \n+struct dst_entry;\n+\n struct in_ifaddr {\n \tstruct hlist_node\thash;\n \tstruct in_ifaddr\t*ifa_next;\n@@ -149,6 +151,7 @@ struct in_ifaddr {\n \t__u32\t\t\tifa_preferred_lft;\n \tunsigned long\t\tifa_cstamp; /* created timestamp */\n \tunsigned long\t\tifa_tstamp; /* updated timestamp */\n+\tstruct dst_entry\t*dst; /* local route to self */\n };\n \n struct in_validator_info {\n@@ -180,6 +183,7 @@ __be32 inet_confirm_addr(struct net *net, struct in_device *in_dev, __be32 dst,\n struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,\n \t\t\t\t    __be32 mask);\n struct in_ifaddr *inet_lookup_ifaddr_rcu(struct net *net, __be32 addr);\n+struct dst_entry *inet_get_ifaddr_dst_rcu(struct net *net, __be32 addr);\n static __inline__ bool inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)\n {\n \treturn !((addr^ifa->ifa_address)&ifa->ifa_mask);\ndiff --git a/include/net/addrconf.h b/include/net/addrconf.h\nindex 87981cd63180..bdfa3306a4c5 100644\n--- a/include/net/addrconf.h\n+++ b/include/net/addrconf.h\n@@ -87,6 +87,9 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,\n \t\t\t\t     const struct in6_addr *addr,\n \t\t\t\t     struct net_device *dev, int strict);\n \n+struct dst_entry *inet6_get_ifaddr_dst_rcu_bh(struct net *net,\n+\t\t\t\t\t      const struct in6_addr *addr);\n+\n int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,\n \t\t       const struct in6_addr *daddr, unsigned int srcprefs,\n \t\t       struct in6_addr *saddr);\ndiff --git a/include/net/if_inet6.h b/include/net/if_inet6.h\nindex d4088d1a688d..1dd42e7c17a4 100644\n--- a/include/net/if_inet6.h\n+++ b/include/net/if_inet6.h\n@@ -39,6 +39,8 @@ enum {\n \tINET6_IFADDR_STATE_DEAD,\n };\n \n+struct dst_entry;\n+\n struct inet6_ifaddr {\n \tstruct in6_addr\t\taddr;\n \t__u32\t\t\tprefix_len;\n@@ -77,6 +79,8 @@ struct inet6_ifaddr {\n \n \tstruct rcu_head\t\trcu;\n \tstruct in6_addr\t\tpeer_addr;\n+\n+\tstruct dst_entry\t*dst; /* local route to self */\n };\n \n struct ip6_sf_socklist {\ndiff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c\nindex 7ce22a2c07ce..a7748f787866 100644\n--- a/net/ipv4/devinet.c\n+++ b/net/ipv4/devinet.c\n@@ -179,6 +179,17 @@ struct in_ifaddr *inet_lookup_ifaddr_rcu(struct net *net, __be32 addr)\n \treturn NULL;\n }\n \n+/* called under RCU lock */\n+struct dst_entry *inet_get_ifaddr_dst_rcu(struct net *net, __be32 addr)\n+{\n+\tstruct in_ifaddr *ifa = inet_lookup_ifaddr_rcu(net, addr);\n+\n+\tif (!ifa)\n+\t\treturn NULL;\n+\n+\treturn dst_access(&ifa->dst, 0);\n+}\n+\n static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);\n \n static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);\n@@ -337,6 +348,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,\n \tstruct in_ifaddr *last_prim = in_dev->ifa_list;\n \tstruct in_ifaddr *prev_prom = NULL;\n \tint do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);\n+\tstruct dst_entry *dst;\n \n \tASSERT_RTNL();\n \n@@ -395,7 +407,12 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,\n \t*ifap = ifa1->ifa_next;\n \tinet_hash_remove(ifa1);\n \n-\t/* 3. Announce address deletion */\n+\t/* 3. Clear dst cache */\n+\n+\tdst = xchg(&ifa1->dst, NULL);\n+\tdst_release(dst);\n+\n+\t/* 4. Announce address deletion */\n \n \t/* Send message first, then call notifier.\n \t   At first sight, FIB update triggered by notifier\n@@ -449,6 +466,7 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,\n \tstruct in_device *in_dev = ifa->ifa_dev;\n \tstruct in_ifaddr *ifa1, **ifap, **last_primary;\n \tstruct in_validator_info ivi;\n+\tstruct rtable *rt;\n \tint ret;\n \n \tASSERT_RTNL();\n@@ -516,6 +534,15 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,\n \trtmsg_ifa(RTM_NEWADDR, ifa, nlh, portid);\n \tblocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);\n \n+\t/* fill the dst cache and transfer the dst ownership to it */\n+\trt = ip_local_route_alloc(in_dev->dev, 0, 0, RTN_LOCAL, false);\n+\tif (rt) {\n+\t\t/* the local route will be valid for till the address will be\n+\t\t * up\n+\t\t */\n+\t\trt->dst.obsolete = DST_OBSOLETE_NONE;\n+\t\t__dst_update(&ifa->dst, &rt->dst);\n+\t}\n \treturn 0;\n }\n \ndiff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c\nindex 5940062cac8d..5fa8d1b764ca 100644\n--- a/net/ipv6/addrconf.c\n+++ b/net/ipv6/addrconf.c\n@@ -904,6 +904,26 @@ static int addrconf_fixup_linkdown(struct ctl_table *table, int *p, int newf)\n \n #endif\n \n+static void inet6_addr_dst_clear(struct inet6_ifaddr *ifp)\n+{\n+\tdst_release(xchg(&ifp->dst, NULL));\n+}\n+\n+static void inet6_addr_dst_update(struct inet6_dev *idev,\n+\t\t\t\t  struct inet6_ifaddr *ifp)\n+{\n+\tstruct rt6_info *rt = addrconf_dst_alloc(idev, &ifp->addr, false);\n+\n+\tif (IS_ERR(rt))\n+\t\treturn;\n+\n+\t/* we are going to manully clear the cache when the related dev will\n+\t * go down\n+\t */\n+\trt->dst.obsolete = DST_OBSOLETE_NONE;\n+\t__dst_update(&ifp->dst, &rt->dst);\n+}\n+\n /* Nobody refers to this ifaddr, destroy it */\n void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)\n {\n@@ -914,6 +934,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)\n #endif\n \n \tin6_dev_put(ifp->idev);\n+\tinet6_addr_dst_clear(ifp);\n \n \tif (cancel_delayed_work(&ifp->dad_work))\n \t\tpr_notice(\"delayed DAD work was pending while freeing ifa=%p\\n\",\n@@ -1907,6 +1928,18 @@ int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)\n }\n EXPORT_SYMBOL(ipv6_chk_prefix);\n \n+/* called under RCU lock */\n+struct dst_entry *inet6_get_ifaddr_dst_rcu_bh(struct net *net,\n+\t\t\t\t\t      const struct in6_addr *addr)\n+{\n+\tstruct inet6_ifaddr *ifp = ipv6_lookup_ifaddr_rcu_bh(net, addr);\n+\n+\tif (!ifp)\n+\t\treturn NULL;\n+\n+\treturn dst_access(&ifp->dst, 0);\n+}\n+\n struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,\n \t\t\t\t     struct net_device *dev, int strict)\n {\n@@ -3300,6 +3333,15 @@ static int fixup_permanent_addr(struct inet6_dev *idev,\n \t\tifp->rt = rt;\n \t\tspin_unlock(&ifp->lock);\n \n+\t\t/* if dad is not going to start, we must cache the new route\n+\t\t * elsewhere we can just clear the old one\n+\t\t */\n+\t\tif (ifp->state == INET6_IFADDR_STATE_PREDAD ||\n+\t\t    ifp->flags & IFA_F_TENTATIVE)\n+\t\t\tinet6_addr_dst_clear(ifp);\n+\t\telse\n+\t\t\tinet6_addr_dst_update(idev, ifp);\n+\n \t\tip6_rt_put(prev);\n \t}\n \n@@ -3679,6 +3721,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)\n \n \t\tspin_unlock_bh(&ifa->lock);\n \n+\t\tinet6_addr_dst_clear(ifa);\n \t\tif (rt)\n \t\t\tip6_del_rt(rt);\n \n@@ -4009,6 +4052,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id)\n \t */\n \n \tipv6_ifa_notify(RTM_NEWADDR, ifp);\n+\tinet6_addr_dst_update(ifp->idev, ifp);\n \n \t/* If added prefix is link local and we are prepared to process\n \t   router advertisements, start sending router solicitations.\n",
    "prefixes": [
        "RFC",
        "08/11"
    ]
}