linux/net/dccp/ipv6.c
<<
>>
Prefs
   1/*
   2 *      DCCP over IPv6
   3 *      Linux INET6 implementation
   4 *
   5 *      Based on net/dccp6/ipv6.c
   6 *
   7 *      Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
   8 *
   9 *      This program is free software; you can redistribute it and/or
  10 *      modify it under the terms of the GNU General Public License
  11 *      as published by the Free Software Foundation; either version
  12 *      2 of the License, or (at your option) any later version.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/random.h>
  17#include <linux/slab.h>
  18#include <linux/xfrm.h>
  19
  20#include <net/addrconf.h>
  21#include <net/inet_common.h>
  22#include <net/inet_hashtables.h>
  23#include <net/inet_sock.h>
  24#include <net/inet6_connection_sock.h>
  25#include <net/inet6_hashtables.h>
  26#include <net/ip6_route.h>
  27#include <net/ipv6.h>
  28#include <net/protocol.h>
  29#include <net/transp_v6.h>
  30#include <net/ip6_checksum.h>
  31#include <net/xfrm.h>
  32#include <net/secure_seq.h>
  33
  34#include "dccp.h"
  35#include "ipv6.h"
  36#include "feat.h"
  37
  38/* The per-net dccp.v6_ctl_sk is used for sending RSTs and ACKs */
  39
  40static const struct inet_connection_sock_af_ops dccp_ipv6_mapped;
  41static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
  42
  43static void dccp_v6_hash(struct sock *sk)
  44{
  45        if (sk->sk_state != DCCP_CLOSED) {
  46                if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
  47                        inet_hash(sk);
  48                        return;
  49                }
  50                local_bh_disable();
  51                __inet6_hash(sk, NULL);
  52                local_bh_enable();
  53        }
  54}
  55
  56/* add pseudo-header to DCCP checksum stored in skb->csum */
  57static inline __sum16 dccp_v6_csum_finish(struct sk_buff *skb,
  58                                      const struct in6_addr *saddr,
  59                                      const struct in6_addr *daddr)
  60{
  61        return csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_DCCP, skb->csum);
  62}
  63
  64static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb)
  65{
  66        struct ipv6_pinfo *np = inet6_sk(sk);
  67        struct dccp_hdr *dh = dccp_hdr(skb);
  68
  69        dccp_csum_outgoing(skb);
  70        dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr);
  71}
  72
  73static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
  74{
  75        return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
  76                                             ipv6_hdr(skb)->saddr.s6_addr32,
  77                                             dccp_hdr(skb)->dccph_dport,
  78                                             dccp_hdr(skb)->dccph_sport     );
  79
  80}
  81
  82static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
  83                        u8 type, u8 code, int offset, __be32 info)
  84{
  85        const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
  86        const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
  87        struct dccp_sock *dp;
  88        struct ipv6_pinfo *np;
  89        struct sock *sk;
  90        int err;
  91        __u64 seq;
  92        struct net *net = dev_net(skb->dev);
  93
  94        if (skb->len < offset + sizeof(*dh) ||
  95            skb->len < offset + __dccp_basic_hdr_len(dh)) {
  96                ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
  97                                   ICMP6_MIB_INERRORS);
  98                return;
  99        }
 100
 101        sk = inet6_lookup(net, &dccp_hashinfo,
 102                        &hdr->daddr, dh->dccph_dport,
 103                        &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
 104
 105        if (sk == NULL) {
 106                ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
 107                                   ICMP6_MIB_INERRORS);
 108                return;
 109        }
 110
 111        if (sk->sk_state == DCCP_TIME_WAIT) {
 112                inet_twsk_put(inet_twsk(sk));
 113                return;
 114        }
 115
 116        bh_lock_sock(sk);
 117        if (sock_owned_by_user(sk))
 118                NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
 119
 120        if (sk->sk_state == DCCP_CLOSED)
 121                goto out;
 122
 123        dp = dccp_sk(sk);
 124        seq = dccp_hdr_seq(dh);
 125        if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
 126            !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
 127                NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
 128                goto out;
 129        }
 130
 131        np = inet6_sk(sk);
 132
 133        if (type == NDISC_REDIRECT) {
 134                struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
 135
 136                if (dst)
 137                        dst->ops->redirect(dst, sk, skb);
 138        }
 139
 140        if (type == ICMPV6_PKT_TOOBIG) {
 141                struct dst_entry *dst = NULL;
 142
 143                if (sock_owned_by_user(sk))
 144                        goto out;
 145                if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
 146                        goto out;
 147
 148                dst = inet6_csk_update_pmtu(sk, ntohl(info));
 149                if (!dst)
 150                        goto out;
 151
 152                if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst))
 153                        dccp_sync_mss(sk, dst_mtu(dst));
 154                goto out;
 155        }
 156
 157        icmpv6_err_convert(type, code, &err);
 158
 159        /* Might be for an request_sock */
 160        switch (sk->sk_state) {
 161                struct request_sock *req, **prev;
 162        case DCCP_LISTEN:
 163                if (sock_owned_by_user(sk))
 164                        goto out;
 165
 166                req = inet6_csk_search_req(sk, &prev, dh->dccph_dport,
 167                                           &hdr->daddr, &hdr->saddr,
 168                                           inet6_iif(skb));
 169                if (req == NULL)
 170                        goto out;
 171
 172                /*
 173                 * ICMPs are not backlogged, hence we cannot get an established
 174                 * socket here.
 175                 */
 176                WARN_ON(req->sk != NULL);
 177
 178                if (!between48(seq, dccp_rsk(req)->dreq_iss,
 179                                    dccp_rsk(req)->dreq_gss)) {
 180                        NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
 181                        goto out;
 182                }
 183
 184                inet_csk_reqsk_queue_drop(sk, req, prev);
 185                goto out;
 186
 187        case DCCP_REQUESTING:
 188        case DCCP_RESPOND:  /* Cannot happen.
 189                               It can, it SYNs are crossed. --ANK */
 190                if (!sock_owned_by_user(sk)) {
 191                        DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
 192                        sk->sk_err = err;
 193                        /*
 194                         * Wake people up to see the error
 195                         * (see connect in sock.c)
 196                         */
 197                        sk->sk_error_report(sk);
 198                        dccp_done(sk);
 199                } else
 200                        sk->sk_err_soft = err;
 201                goto out;
 202        }
 203
 204        if (!sock_owned_by_user(sk) && np->recverr) {
 205                sk->sk_err = err;
 206                sk->sk_error_report(sk);
 207        } else
 208                sk->sk_err_soft = err;
 209
 210out:
 211        bh_unlock_sock(sk);
 212        sock_put(sk);
 213}
 214
 215
 216static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
 217                                 struct request_values *rv_unused)
 218{
 219        struct inet6_request_sock *ireq6 = inet6_rsk(req);
 220        struct ipv6_pinfo *np = inet6_sk(sk);
 221        struct sk_buff *skb;
 222        struct in6_addr *final_p, final;
 223        struct flowi6 fl6;
 224        int err = -1;
 225        struct dst_entry *dst;
 226
 227        memset(&fl6, 0, sizeof(fl6));
 228        fl6.flowi6_proto = IPPROTO_DCCP;
 229        fl6.daddr = ireq6->rmt_addr;
 230        fl6.saddr = ireq6->loc_addr;
 231        fl6.flowlabel = 0;
 232        fl6.flowi6_oif = ireq6->iif;
 233        fl6.fl6_dport = inet_rsk(req)->rmt_port;
 234        fl6.fl6_sport = inet_rsk(req)->loc_port;
 235        security_req_classify_flow(req, flowi6_to_flowi(&fl6));
 236
 237
 238        final_p = fl6_update_dst(&fl6, np->opt, &final);
 239
 240        dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
 241        if (IS_ERR(dst)) {
 242                err = PTR_ERR(dst);
 243                dst = NULL;
 244                goto done;
 245        }
 246
 247        skb = dccp_make_response(sk, dst, req);
 248        if (skb != NULL) {
 249                struct dccp_hdr *dh = dccp_hdr(skb);
 250
 251                dh->dccph_checksum = dccp_v6_csum_finish(skb,
 252                                                         &ireq6->loc_addr,
 253                                                         &ireq6->rmt_addr);
 254                fl6.daddr = ireq6->rmt_addr;
 255                err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
 256                err = net_xmit_eval(err);
 257        }
 258
 259done:
 260        dst_release(dst);
 261        return err;
 262}
 263
 264static void dccp_v6_reqsk_destructor(struct request_sock *req)
 265{
 266        dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
 267        if (inet6_rsk(req)->pktopts != NULL)
 268                kfree_skb(inet6_rsk(req)->pktopts);
 269}
 270
 271static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
 272{
 273        const struct ipv6hdr *rxip6h;
 274        struct sk_buff *skb;
 275        struct flowi6 fl6;
 276        struct net *net = dev_net(skb_dst(rxskb)->dev);
 277        struct sock *ctl_sk = net->dccp.v6_ctl_sk;
 278        struct dst_entry *dst;
 279
 280        if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
 281                return;
 282
 283        if (!ipv6_unicast_destination(rxskb))
 284                return;
 285
 286        skb = dccp_ctl_make_reset(ctl_sk, rxskb);
 287        if (skb == NULL)
 288                return;
 289
 290        rxip6h = ipv6_hdr(rxskb);
 291        dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr,
 292                                                            &rxip6h->daddr);
 293
 294        memset(&fl6, 0, sizeof(fl6));
 295        fl6.daddr = rxip6h->saddr;
 296        fl6.saddr = rxip6h->daddr;
 297
 298        fl6.flowi6_proto = IPPROTO_DCCP;
 299        fl6.flowi6_oif = inet6_iif(rxskb);
 300        fl6.fl6_dport = dccp_hdr(skb)->dccph_dport;
 301        fl6.fl6_sport = dccp_hdr(skb)->dccph_sport;
 302        security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
 303
 304        /* sk = NULL, but it is safe for now. RST socket required. */
 305        dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false);
 306        if (!IS_ERR(dst)) {
 307                skb_dst_set(skb, dst);
 308                ip6_xmit(ctl_sk, skb, &fl6, NULL, 0);
 309                DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
 310                DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
 311                return;
 312        }
 313
 314        kfree_skb(skb);
 315}
 316
 317static struct request_sock_ops dccp6_request_sock_ops = {
 318        .family         = AF_INET6,
 319        .obj_size       = sizeof(struct dccp6_request_sock),
 320        .rtx_syn_ack    = dccp_v6_send_response,
 321        .send_ack       = dccp_reqsk_send_ack,
 322        .destructor     = dccp_v6_reqsk_destructor,
 323        .send_reset     = dccp_v6_ctl_send_reset,
 324        .syn_ack_timeout = dccp_syn_ack_timeout,
 325};
 326
 327static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
 328{
 329        const struct dccp_hdr *dh = dccp_hdr(skb);
 330        const struct ipv6hdr *iph = ipv6_hdr(skb);
 331        struct sock *nsk;
 332        struct request_sock **prev;
 333        /* Find possible connection requests. */
 334        struct request_sock *req = inet6_csk_search_req(sk, &prev,
 335                                                        dh->dccph_sport,
 336                                                        &iph->saddr,
 337                                                        &iph->daddr,
 338                                                        inet6_iif(skb));
 339        if (req != NULL)
 340                return dccp_check_req(sk, skb, req, prev);
 341
 342        nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo,
 343                                         &iph->saddr, dh->dccph_sport,
 344                                         &iph->daddr, ntohs(dh->dccph_dport),
 345                                         inet6_iif(skb));
 346        if (nsk != NULL) {
 347                if (nsk->sk_state != DCCP_TIME_WAIT) {
 348                        bh_lock_sock(nsk);
 349                        return nsk;
 350                }
 351                inet_twsk_put(inet_twsk(nsk));
 352                return NULL;
 353        }
 354
 355        return sk;
 356}
 357
 358static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 359{
 360        struct request_sock *req;
 361        struct dccp_request_sock *dreq;
 362        struct inet6_request_sock *ireq6;
 363        struct ipv6_pinfo *np = inet6_sk(sk);
 364        const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
 365        struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 366
 367        if (skb->protocol == htons(ETH_P_IP))
 368                return dccp_v4_conn_request(sk, skb);
 369
 370        if (!ipv6_unicast_destination(skb))
 371                return 0;       /* discard, don't send a reset here */
 372
 373        if (dccp_bad_service_code(sk, service)) {
 374                dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
 375                goto drop;
 376        }
 377        /*
 378         * There are no SYN attacks on IPv6, yet...
 379         */
 380        dcb->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY;
 381        if (inet_csk_reqsk_queue_is_full(sk))
 382                goto drop;
 383
 384        if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
 385                goto drop;
 386
 387        req = inet6_reqsk_alloc(&dccp6_request_sock_ops);
 388        if (req == NULL)
 389                goto drop;
 390
 391        if (dccp_reqsk_init(req, dccp_sk(sk), skb))
 392                goto drop_and_free;
 393
 394        dreq = dccp_rsk(req);
 395        if (dccp_parse_options(sk, dreq, skb))
 396                goto drop_and_free;
 397
 398        if (security_inet_conn_request(sk, skb, req))
 399                goto drop_and_free;
 400
 401        ireq6 = inet6_rsk(req);
 402        ireq6->rmt_addr = ipv6_hdr(skb)->saddr;
 403        ireq6->loc_addr = ipv6_hdr(skb)->daddr;
 404
 405        if (ipv6_opt_accepted(sk, skb) ||
 406            np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
 407            np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
 408                atomic_inc(&skb->users);
 409                ireq6->pktopts = skb;
 410        }
 411        ireq6->iif = sk->sk_bound_dev_if;
 412
 413        /* So that link locals have meaning */
 414        if (!sk->sk_bound_dev_if &&
 415            ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL)
 416                ireq6->iif = inet6_iif(skb);
 417
 418        /*
 419         * Step 3: Process LISTEN state
 420         *
 421         *   Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
 422         *
 423         * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
 424         */
 425        dreq->dreq_isr     = dcb->dccpd_seq;
 426        dreq->dreq_gsr     = dreq->dreq_isr;
 427        dreq->dreq_iss     = dccp_v6_init_sequence(skb);
 428        dreq->dreq_gss     = dreq->dreq_iss;
 429        dreq->dreq_service = service;
 430
 431        if (dccp_v6_send_response(sk, req, NULL))
 432                goto drop_and_free;
 433
 434        inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
 435        return 0;
 436
 437drop_and_free:
 438        reqsk_free(req);
 439drop:
 440        DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
 441        return -1;
 442}
 443
 444static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
 445                                              struct sk_buff *skb,
 446                                              struct request_sock *req,
 447                                              struct dst_entry *dst)
 448{
 449        struct inet6_request_sock *ireq6 = inet6_rsk(req);
 450        struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 451        struct inet_sock *newinet;
 452        struct dccp6_sock *newdp6;
 453        struct sock *newsk;
 454
 455        if (skb->protocol == htons(ETH_P_IP)) {
 456                /*
 457                 *      v6 mapped
 458                 */
 459                newsk = dccp_v4_request_recv_sock(sk, skb, req, dst);
 460                if (newsk == NULL)
 461                        return NULL;
 462
 463                newdp6 = (struct dccp6_sock *)newsk;
 464                newinet = inet_sk(newsk);
 465                newinet->pinet6 = &newdp6->inet6;
 466                newnp = inet6_sk(newsk);
 467
 468                memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 469
 470                ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr);
 471
 472                ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr);
 473
 474                newnp->rcv_saddr = newnp->saddr;
 475
 476                inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
 477                newsk->sk_backlog_rcv = dccp_v4_do_rcv;
 478                newnp->pktoptions  = NULL;
 479                newnp->opt         = NULL;
 480                newnp->mcast_oif   = inet6_iif(skb);
 481                newnp->mcast_hops  = ipv6_hdr(skb)->hop_limit;
 482
 483                /*
 484                 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
 485                 * here, dccp_create_openreq_child now does this for us, see the comment in
 486                 * that function for the gory details. -acme
 487                 */
 488
 489                /* It is tricky place. Until this moment IPv4 tcp
 490                   worked with IPv6 icsk.icsk_af_ops.
 491                   Sync it now.
 492                 */
 493                dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
 494
 495                return newsk;
 496        }
 497
 498
 499        if (sk_acceptq_is_full(sk))
 500                goto out_overflow;
 501
 502        if (dst == NULL) {
 503                struct in6_addr *final_p, final;
 504                struct flowi6 fl6;
 505
 506                memset(&fl6, 0, sizeof(fl6));
 507                fl6.flowi6_proto = IPPROTO_DCCP;
 508                fl6.daddr = ireq6->rmt_addr;
 509                final_p = fl6_update_dst(&fl6, np->opt, &final);
 510                fl6.saddr = ireq6->loc_addr;
 511                fl6.flowi6_oif = sk->sk_bound_dev_if;
 512                fl6.fl6_dport = inet_rsk(req)->rmt_port;
 513                fl6.fl6_sport = inet_rsk(req)->loc_port;
 514                security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 515
 516                dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
 517                if (IS_ERR(dst))
 518                        goto out;
 519        }
 520
 521        newsk = dccp_create_openreq_child(sk, req, skb);
 522        if (newsk == NULL)
 523                goto out_nonewsk;
 524
 525        /*
 526         * No need to charge this sock to the relevant IPv6 refcnt debug socks
 527         * count here, dccp_create_openreq_child now does this for us, see the
 528         * comment in that function for the gory details. -acme
 529         */
 530
 531        __ip6_dst_store(newsk, dst, NULL, NULL);
 532        newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
 533                                                      NETIF_F_TSO);
 534        newdp6 = (struct dccp6_sock *)newsk;
 535        newinet = inet_sk(newsk);
 536        newinet->pinet6 = &newdp6->inet6;
 537        newnp = inet6_sk(newsk);
 538
 539        memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 540
 541        newnp->daddr = ireq6->rmt_addr;
 542        newnp->saddr = ireq6->loc_addr;
 543        newnp->rcv_saddr = ireq6->loc_addr;
 544        newsk->sk_bound_dev_if = ireq6->iif;
 545
 546        /* Now IPv6 options...
 547
 548           First: no IPv4 options.
 549         */
 550        newinet->inet_opt = NULL;
 551
 552        /* Clone RX bits */
 553        newnp->rxopt.all = np->rxopt.all;
 554
 555        /* Clone pktoptions received with SYN */
 556        newnp->pktoptions = NULL;
 557        if (ireq6->pktopts != NULL) {
 558                newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC);
 559                consume_skb(ireq6->pktopts);
 560                ireq6->pktopts = NULL;
 561                if (newnp->pktoptions)
 562                        skb_set_owner_r(newnp->pktoptions, newsk);
 563        }
 564        newnp->opt        = NULL;
 565        newnp->mcast_oif  = inet6_iif(skb);
 566        newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
 567
 568        /*
 569         * Clone native IPv6 options from listening socket (if any)
 570         *
 571         * Yes, keeping reference count would be much more clever, but we make
 572         * one more one thing there: reattach optmem to newsk.
 573         */
 574        if (np->opt != NULL)
 575                newnp->opt = ipv6_dup_options(newsk, np->opt);
 576
 577        inet_csk(newsk)->icsk_ext_hdr_len = 0;
 578        if (newnp->opt != NULL)
 579                inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
 580                                                     newnp->opt->opt_flen);
 581
 582        dccp_sync_mss(newsk, dst_mtu(dst));
 583
 584        newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
 585        newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
 586
 587        if (__inet_inherit_port(sk, newsk) < 0) {
 588                inet_csk_prepare_forced_close(newsk);
 589                dccp_done(newsk);
 590                goto out;
 591        }
 592        __inet6_hash(newsk, NULL);
 593
 594        return newsk;
 595
 596out_overflow:
 597        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
 598out_nonewsk:
 599        dst_release(dst);
 600out:
 601        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
 602        return NULL;
 603}
 604
 605/* The socket must have it's spinlock held when we get
 606 * here.
 607 *
 608 * We have a potential double-lock case here, so even when
 609 * doing backlog processing we use the BH locking scheme.
 610 * This is because we cannot sleep with the original spinlock
 611 * held.
 612 */
 613static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 614{
 615        struct ipv6_pinfo *np = inet6_sk(sk);
 616        struct sk_buff *opt_skb = NULL;
 617
 618        /* Imagine: socket is IPv6. IPv4 packet arrives,
 619           goes to IPv4 receive handler and backlogged.
 620           From backlog it always goes here. Kerboom...
 621           Fortunately, dccp_rcv_established and rcv_established
 622           handle them correctly, but it is not case with
 623           dccp_v6_hnd_req and dccp_v6_ctl_send_reset().   --ANK
 624         */
 625
 626        if (skb->protocol == htons(ETH_P_IP))
 627                return dccp_v4_do_rcv(sk, skb);
 628
 629        if (sk_filter(sk, skb))
 630                goto discard;
 631
 632        /*
 633         * socket locking is here for SMP purposes as backlog rcv is currently
 634         * called with bh processing disabled.
 635         */
 636
 637        /* Do Stevens' IPV6_PKTOPTIONS.
 638
 639           Yes, guys, it is the only place in our code, where we
 640           may make it not affecting IPv4.
 641           The rest of code is protocol independent,
 642           and I do not like idea to uglify IPv4.
 643
 644           Actually, all the idea behind IPV6_PKTOPTIONS
 645           looks not very well thought. For now we latch
 646           options, received in the last packet, enqueued
 647           by tcp. Feel free to propose better solution.
 648                                               --ANK (980728)
 649         */
 650        if (np->rxopt.all)
 651        /*
 652         * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below
 653         *        (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example.
 654         */
 655                opt_skb = skb_clone(skb, GFP_ATOMIC);
 656
 657        if (sk->sk_state == DCCP_OPEN) { /* Fast path */
 658                if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
 659                        goto reset;
 660                if (opt_skb) {
 661                        /* XXX This is where we would goto ipv6_pktoptions. */
 662                        __kfree_skb(opt_skb);
 663                }
 664                return 0;
 665        }
 666
 667        /*
 668         *  Step 3: Process LISTEN state
 669         *     If S.state == LISTEN,
 670         *       If P.type == Request or P contains a valid Init Cookie option,
 671         *            (* Must scan the packet's options to check for Init
 672         *               Cookies.  Only Init Cookies are processed here,
 673         *               however; other options are processed in Step 8.  This
 674         *               scan need only be performed if the endpoint uses Init
 675         *               Cookies *)
 676         *            (* Generate a new socket and switch to that socket *)
 677         *            Set S := new socket for this port pair
 678         *            S.state = RESPOND
 679         *            Choose S.ISS (initial seqno) or set from Init Cookies
 680         *            Initialize S.GAR := S.ISS
 681         *            Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
 682         *            Continue with S.state == RESPOND
 683         *            (* A Response packet will be generated in Step 11 *)
 684         *       Otherwise,
 685         *            Generate Reset(No Connection) unless P.type == Reset
 686         *            Drop packet and return
 687         *
 688         * NOTE: the check for the packet types is done in
 689         *       dccp_rcv_state_process
 690         */
 691        if (sk->sk_state == DCCP_LISTEN) {
 692                struct sock *nsk = dccp_v6_hnd_req(sk, skb);
 693
 694                if (nsk == NULL)
 695                        goto discard;
 696                /*
 697                 * Queue it on the new socket if the new socket is active,
 698                 * otherwise we just shortcircuit this and continue with
 699                 * the new socket..
 700                 */
 701                if (nsk != sk) {
 702                        if (dccp_child_process(sk, nsk, skb))
 703                                goto reset;
 704                        if (opt_skb != NULL)
 705                                __kfree_skb(opt_skb);
 706                        return 0;
 707                }
 708        }
 709
 710        if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
 711                goto reset;
 712        if (opt_skb) {
 713                /* XXX This is where we would goto ipv6_pktoptions. */
 714                __kfree_skb(opt_skb);
 715        }
 716        return 0;
 717
 718reset:
 719        dccp_v6_ctl_send_reset(sk, skb);
 720discard:
 721        if (opt_skb != NULL)
 722                __kfree_skb(opt_skb);
 723        kfree_skb(skb);
 724        return 0;
 725}
 726
 727static int dccp_v6_rcv(struct sk_buff *skb)
 728{
 729        const struct dccp_hdr *dh;
 730        struct sock *sk;
 731        int min_cov;
 732
 733        /* Step 1: Check header basics */
 734
 735        if (dccp_invalid_packet(skb))
 736                goto discard_it;
 737
 738        /* Step 1: If header checksum is incorrect, drop packet and return. */
 739        if (dccp_v6_csum_finish(skb, &ipv6_hdr(skb)->saddr,
 740                                     &ipv6_hdr(skb)->daddr)) {
 741                DCCP_WARN("dropped packet with invalid checksum\n");
 742                goto discard_it;
 743        }
 744
 745        dh = dccp_hdr(skb);
 746
 747        DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(dh);
 748        DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
 749
 750        if (dccp_packet_without_ack(skb))
 751                DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
 752        else
 753                DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
 754
 755        /* Step 2:
 756         *      Look up flow ID in table and get corresponding socket */
 757        sk = __inet6_lookup_skb(&dccp_hashinfo, skb,
 758                                dh->dccph_sport, dh->dccph_dport);
 759        /*
 760         * Step 2:
 761         *      If no socket ...
 762         */
 763        if (sk == NULL) {
 764                dccp_pr_debug("failed to look up flow ID in table and "
 765                              "get corresponding socket\n");
 766                goto no_dccp_socket;
 767        }
 768
 769        /*
 770         * Step 2:
 771         *      ... or S.state == TIMEWAIT,
 772         *              Generate Reset(No Connection) unless P.type == Reset
 773         *              Drop packet and return
 774         */
 775        if (sk->sk_state == DCCP_TIME_WAIT) {
 776                dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
 777                inet_twsk_put(inet_twsk(sk));
 778                goto no_dccp_socket;
 779        }
 780
 781        /*
 782         * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
 783         *      o if MinCsCov = 0, only packets with CsCov = 0 are accepted
 784         *      o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
 785         */
 786        min_cov = dccp_sk(sk)->dccps_pcrlen;
 787        if (dh->dccph_cscov  &&  (min_cov == 0 || dh->dccph_cscov < min_cov))  {
 788                dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d\n",
 789                              dh->dccph_cscov, min_cov);
 790                /* FIXME: send Data Dropped option (see also dccp_v4_rcv) */
 791                goto discard_and_relse;
 792        }
 793
 794        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
 795                goto discard_and_relse;
 796
 797        return sk_receive_skb(sk, skb, 1) ? -1 : 0;
 798
 799no_dccp_socket:
 800        if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
 801                goto discard_it;
 802        /*
 803         * Step 2:
 804         *      If no socket ...
 805         *              Generate Reset(No Connection) unless P.type == Reset
 806         *              Drop packet and return
 807         */
 808        if (dh->dccph_type != DCCP_PKT_RESET) {
 809                DCCP_SKB_CB(skb)->dccpd_reset_code =
 810                                        DCCP_RESET_CODE_NO_CONNECTION;
 811                dccp_v6_ctl_send_reset(sk, skb);
 812        }
 813
 814discard_it:
 815        kfree_skb(skb);
 816        return 0;
 817
 818discard_and_relse:
 819        sock_put(sk);
 820        goto discard_it;
 821}
 822
 823static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 824                           int addr_len)
 825{
 826        struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
 827        struct inet_connection_sock *icsk = inet_csk(sk);
 828        struct inet_sock *inet = inet_sk(sk);
 829        struct ipv6_pinfo *np = inet6_sk(sk);
 830        struct dccp_sock *dp = dccp_sk(sk);
 831        struct in6_addr *saddr = NULL, *final_p, final;
 832        struct flowi6 fl6;
 833        struct dst_entry *dst;
 834        int addr_type;
 835        int err;
 836
 837        dp->dccps_role = DCCP_ROLE_CLIENT;
 838
 839        if (addr_len < SIN6_LEN_RFC2133)
 840                return -EINVAL;
 841
 842        if (usin->sin6_family != AF_INET6)
 843                return -EAFNOSUPPORT;
 844
 845        memset(&fl6, 0, sizeof(fl6));
 846
 847        if (np->sndflow) {
 848                fl6.flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
 849                IP6_ECN_flow_init(fl6.flowlabel);
 850                if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) {
 851                        struct ip6_flowlabel *flowlabel;
 852                        flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
 853                        if (flowlabel == NULL)
 854                                return -EINVAL;
 855                        usin->sin6_addr = flowlabel->dst;
 856                        fl6_sock_release(flowlabel);
 857                }
 858        }
 859        /*
 860         * connect() to INADDR_ANY means loopback (BSD'ism).
 861         */
 862        if (ipv6_addr_any(&usin->sin6_addr))
 863                usin->sin6_addr.s6_addr[15] = 1;
 864
 865        addr_type = ipv6_addr_type(&usin->sin6_addr);
 866
 867        if (addr_type & IPV6_ADDR_MULTICAST)
 868                return -ENETUNREACH;
 869
 870        if (addr_type & IPV6_ADDR_LINKLOCAL) {
 871                if (addr_len >= sizeof(struct sockaddr_in6) &&
 872                    usin->sin6_scope_id) {
 873                        /* If interface is set while binding, indices
 874                         * must coincide.
 875                         */
 876                        if (sk->sk_bound_dev_if &&
 877                            sk->sk_bound_dev_if != usin->sin6_scope_id)
 878                                return -EINVAL;
 879
 880                        sk->sk_bound_dev_if = usin->sin6_scope_id;
 881                }
 882
 883                /* Connect to link-local address requires an interface */
 884                if (!sk->sk_bound_dev_if)
 885                        return -EINVAL;
 886        }
 887
 888        np->daddr = usin->sin6_addr;
 889        np->flow_label = fl6.flowlabel;
 890
 891        /*
 892         * DCCP over IPv4
 893         */
 894        if (addr_type == IPV6_ADDR_MAPPED) {
 895                u32 exthdrlen = icsk->icsk_ext_hdr_len;
 896                struct sockaddr_in sin;
 897
 898                SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
 899
 900                if (__ipv6_only_sock(sk))
 901                        return -ENETUNREACH;
 902
 903                sin.sin_family = AF_INET;
 904                sin.sin_port = usin->sin6_port;
 905                sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
 906
 907                icsk->icsk_af_ops = &dccp_ipv6_mapped;
 908                sk->sk_backlog_rcv = dccp_v4_do_rcv;
 909
 910                err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
 911                if (err) {
 912                        icsk->icsk_ext_hdr_len = exthdrlen;
 913                        icsk->icsk_af_ops = &dccp_ipv6_af_ops;
 914                        sk->sk_backlog_rcv = dccp_v6_do_rcv;
 915                        goto failure;
 916                }
 917                ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
 918                ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->rcv_saddr);
 919
 920                return err;
 921        }
 922
 923        if (!ipv6_addr_any(&np->rcv_saddr))
 924                saddr = &np->rcv_saddr;
 925
 926        fl6.flowi6_proto = IPPROTO_DCCP;
 927        fl6.daddr = np->daddr;
 928        fl6.saddr = saddr ? *saddr : np->saddr;
 929        fl6.flowi6_oif = sk->sk_bound_dev_if;
 930        fl6.fl6_dport = usin->sin6_port;
 931        fl6.fl6_sport = inet->inet_sport;
 932        security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 933
 934        final_p = fl6_update_dst(&fl6, np->opt, &final);
 935
 936        dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
 937        if (IS_ERR(dst)) {
 938                err = PTR_ERR(dst);
 939                goto failure;
 940        }
 941
 942        if (saddr == NULL) {
 943                saddr = &fl6.saddr;
 944                np->rcv_saddr = *saddr;
 945        }
 946
 947        /* set the source address */
 948        np->saddr = *saddr;
 949        inet->inet_rcv_saddr = LOOPBACK4_IPV6;
 950
 951        __ip6_dst_store(sk, dst, NULL, NULL);
 952
 953        icsk->icsk_ext_hdr_len = 0;
 954        if (np->opt != NULL)
 955                icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
 956                                          np->opt->opt_nflen);
 957
 958        inet->inet_dport = usin->sin6_port;
 959
 960        dccp_set_state(sk, DCCP_REQUESTING);
 961        err = inet6_hash_connect(&dccp_death_row, sk);
 962        if (err)
 963                goto late_failure;
 964
 965        dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32,
 966                                                      np->daddr.s6_addr32,
 967                                                      inet->inet_sport,
 968                                                      inet->inet_dport);
 969        err = dccp_connect(sk);
 970        if (err)
 971                goto late_failure;
 972
 973        return 0;
 974
 975late_failure:
 976        dccp_set_state(sk, DCCP_CLOSED);
 977        __sk_dst_reset(sk);
 978failure:
 979        inet->inet_dport = 0;
 980        sk->sk_route_caps = 0;
 981        return err;
 982}
 983
 984static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
 985        .queue_xmit        = inet6_csk_xmit,
 986        .send_check        = dccp_v6_send_check,
 987        .rebuild_header    = inet6_sk_rebuild_header,
 988        .conn_request      = dccp_v6_conn_request,
 989        .syn_recv_sock     = dccp_v6_request_recv_sock,
 990        .net_header_len    = sizeof(struct ipv6hdr),
 991        .setsockopt        = ipv6_setsockopt,
 992        .getsockopt        = ipv6_getsockopt,
 993        .addr2sockaddr     = inet6_csk_addr2sockaddr,
 994        .sockaddr_len      = sizeof(struct sockaddr_in6),
 995        .bind_conflict     = inet6_csk_bind_conflict,
 996#ifdef CONFIG_COMPAT
 997        .compat_setsockopt = compat_ipv6_setsockopt,
 998        .compat_getsockopt = compat_ipv6_getsockopt,
 999#endif
1000};
1001
1002/*
1003 *      DCCP over IPv4 via INET6 API
1004 */
1005static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
1006        .queue_xmit        = ip_queue_xmit,
1007        .send_check        = dccp_v4_send_check,
1008        .rebuild_header    = inet_sk_rebuild_header,
1009        .conn_request      = dccp_v6_conn_request,
1010        .syn_recv_sock     = dccp_v6_request_recv_sock,
1011        .net_header_len    = sizeof(struct iphdr),
1012        .setsockopt        = ipv6_setsockopt,
1013        .getsockopt        = ipv6_getsockopt,
1014        .addr2sockaddr     = inet6_csk_addr2sockaddr,
1015        .sockaddr_len      = sizeof(struct sockaddr_in6),
1016#ifdef CONFIG_COMPAT
1017        .compat_setsockopt = compat_ipv6_setsockopt,
1018        .compat_getsockopt = compat_ipv6_getsockopt,
1019#endif
1020};
1021
1022/* NOTE: A lot of things set to zero explicitly by call to
1023 *       sk_alloc() so need not be done here.
1024 */
1025static int dccp_v6_init_sock(struct sock *sk)
1026{
1027        static __u8 dccp_v6_ctl_sock_initialized;
1028        int err = dccp_init_sock(sk, dccp_v6_ctl_sock_initialized);
1029
1030        if (err == 0) {
1031                if (unlikely(!dccp_v6_ctl_sock_initialized))
1032                        dccp_v6_ctl_sock_initialized = 1;
1033                inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1034        }
1035
1036        return err;
1037}
1038
1039static void dccp_v6_destroy_sock(struct sock *sk)
1040{
1041        dccp_destroy_sock(sk);
1042        inet6_destroy_sock(sk);
1043}
1044
1045static struct timewait_sock_ops dccp6_timewait_sock_ops = {
1046        .twsk_obj_size  = sizeof(struct dccp6_timewait_sock),
1047};
1048
1049static struct proto dccp_v6_prot = {
1050        .name              = "DCCPv6",
1051        .owner             = THIS_MODULE,
1052        .close             = dccp_close,
1053        .connect           = dccp_v6_connect,
1054        .disconnect        = dccp_disconnect,
1055        .ioctl             = dccp_ioctl,
1056        .init              = dccp_v6_init_sock,
1057        .setsockopt        = dccp_setsockopt,
1058        .getsockopt        = dccp_getsockopt,
1059        .sendmsg           = dccp_sendmsg,
1060        .recvmsg           = dccp_recvmsg,
1061        .backlog_rcv       = dccp_v6_do_rcv,
1062        .hash              = dccp_v6_hash,
1063        .unhash            = inet_unhash,
1064        .accept            = inet_csk_accept,
1065        .get_port          = inet_csk_get_port,
1066        .shutdown          = dccp_shutdown,
1067        .destroy           = dccp_v6_destroy_sock,
1068        .orphan_count      = &dccp_orphan_count,
1069        .max_header        = MAX_DCCP_HEADER,
1070        .obj_size          = sizeof(struct dccp6_sock),
1071        .slab_flags        = SLAB_DESTROY_BY_RCU,
1072        .rsk_prot          = &dccp6_request_sock_ops,
1073        .twsk_prot         = &dccp6_timewait_sock_ops,
1074        .h.hashinfo        = &dccp_hashinfo,
1075#ifdef CONFIG_COMPAT
1076        .compat_setsockopt = compat_dccp_setsockopt,
1077        .compat_getsockopt = compat_dccp_getsockopt,
1078#endif
1079};
1080
1081static const struct inet6_protocol dccp_v6_protocol = {
1082        .handler        = dccp_v6_rcv,
1083        .err_handler    = dccp_v6_err,
1084        .flags          = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
1085};
1086
1087static const struct proto_ops inet6_dccp_ops = {
1088        .family            = PF_INET6,
1089        .owner             = THIS_MODULE,
1090        .release           = inet6_release,
1091        .bind              = inet6_bind,
1092        .connect           = inet_stream_connect,
1093        .socketpair        = sock_no_socketpair,
1094        .accept            = inet_accept,
1095        .getname           = inet6_getname,
1096        .poll              = dccp_poll,
1097        .ioctl             = inet6_ioctl,
1098        .listen            = inet_dccp_listen,
1099        .shutdown          = inet_shutdown,
1100        .setsockopt        = sock_common_setsockopt,
1101        .getsockopt        = sock_common_getsockopt,
1102        .sendmsg           = inet_sendmsg,
1103        .recvmsg           = sock_common_recvmsg,
1104        .mmap              = sock_no_mmap,
1105        .sendpage          = sock_no_sendpage,
1106#ifdef CONFIG_COMPAT
1107        .compat_setsockopt = compat_sock_common_setsockopt,
1108        .compat_getsockopt = compat_sock_common_getsockopt,
1109#endif
1110};
1111
1112static struct inet_protosw dccp_v6_protosw = {
1113        .type           = SOCK_DCCP,
1114        .protocol       = IPPROTO_DCCP,
1115        .prot           = &dccp_v6_prot,
1116        .ops            = &inet6_dccp_ops,
1117        .flags          = INET_PROTOSW_ICSK,
1118};
1119
1120static int __net_init dccp_v6_init_net(struct net *net)
1121{
1122        if (dccp_hashinfo.bhash == NULL)
1123                return -ESOCKTNOSUPPORT;
1124
1125        return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
1126                                    SOCK_DCCP, IPPROTO_DCCP, net);
1127}
1128
1129static void __net_exit dccp_v6_exit_net(struct net *net)
1130{
1131        inet_ctl_sock_destroy(net->dccp.v6_ctl_sk);
1132}
1133
1134static struct pernet_operations dccp_v6_ops = {
1135        .init   = dccp_v6_init_net,
1136        .exit   = dccp_v6_exit_net,
1137};
1138
1139static int __init dccp_v6_init(void)
1140{
1141        int err = proto_register(&dccp_v6_prot, 1);
1142
1143        if (err != 0)
1144                goto out;
1145
1146        err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1147        if (err != 0)
1148                goto out_unregister_proto;
1149
1150        inet6_register_protosw(&dccp_v6_protosw);
1151
1152        err = register_pernet_subsys(&dccp_v6_ops);
1153        if (err != 0)
1154                goto out_destroy_ctl_sock;
1155out:
1156        return err;
1157
1158out_destroy_ctl_sock:
1159        inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1160        inet6_unregister_protosw(&dccp_v6_protosw);
1161out_unregister_proto:
1162        proto_unregister(&dccp_v6_prot);
1163        goto out;
1164}
1165
1166static void __exit dccp_v6_exit(void)
1167{
1168        unregister_pernet_subsys(&dccp_v6_ops);
1169        inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1170        inet6_unregister_protosw(&dccp_v6_protosw);
1171        proto_unregister(&dccp_v6_prot);
1172}
1173
1174module_init(dccp_v6_init);
1175module_exit(dccp_v6_exit);
1176
1177/*
1178 * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
1179 * values directly, Also cover the case where the protocol is not specified,
1180 * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
1181 */
1182MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
1183MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
1184MODULE_LICENSE("GPL");
1185MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
1186MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
1187
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.