Hello, I want to do a little experiment here. I want to record myself implementing a feature for the Grispenser 3 project. So let's get right to it. This is Blender 3.6. Can't see the bottom left here, but at the bottom right, sorry. But this is Blender 3.6. And we have this feature where you can have multiple strokes, right, with different materials. And so you have one with a black material, one with a red material. And we have this feature where you can lock a material. And so now I can't select these strokes anymore, but I can still select this one. And this feature doesn't exist right now in Grispenser 3. So I wanted to see if I can get something working in one session and take you along with me. So let's close this. We don't need it anymore. And let me just rebuild. And let's look at where we are right now in Grispenser 3. I prepare a sort of test file here, so we don't have to watch me do that. Linking. Don't really need to use a debug session here, but whatever. So this is the file. Again, we have strokes with different materials, the black one and the red one. But let's say I set the material, so assign material to the active one, which is white here in this case. You can see that it changes for all of them. Wait, which is actually correct. I just noticed that my test file isn't quite right here. Oh, now I'm in edit mode, so I can't undo. We need to fix that. But I need to lock the red material. Make sure to save the file again. And then assign the material, but yeah, so it doesn't work right now. Alright, so we have our test file. That's good. Let's see where do we even start, right? Well, let's look at the operator I just used, which is the stroke material set operator. And see what it does. So here we can see that it gets the active object. It gets the current material index, which is the active material slot. And they are one base, so we have to subtract one to get the index. And then we just go through all of the editable drawings, right? So you could have a lot of them, right? All of the layers and that multi-frame editing. So those are all of the drawings that you're currently editing. And we loop through all of them parallel. And here we get the selected curves as an index mask. And then for each of the selected curves, we basically set this attribute. So we have an attribute called material index. And if it exists already, we get it here, or we add it if it doesn't exist. And then for each of the curves, we set the material to this active material slot. And that's it. So pretty simple. And basically what we want to do here, what we want to change is, we want to make sure that here, instead of just retrieving the selected curves or strokes, we want to somehow include the fact that some of them might not be editable. So really what we want is sort of an index mask of the editable strokes, if I can type. This should actually be const. And so we should put that in the response of namespace. Maybe it could be called something like retrieve editable strokes. There we go. Now because we want to look at the materials and materials can be both on the objects and on the object data. So I think what we have to pass here is the object itself. And then we also want to pass the drawing for which we want to get the editable strokes. So this would be info.drawing. And finally we want to pass the index mask memory here. This index mask memory is basically just a way that we can have sort of, it's almost like the allocator, right? So that we don't have to allocate a bunch of memory for multiple index masks. It's basically just a convenient way to not have to think about where the memory is and do like memory management. I'm sure there are other reasons. But yeah, I think this is sort of what we want to do, right? And then it would just check if that's empty and then don't do anything and otherwise we just go over those and have the curve index here. So that would be the idea. Let's see if we can implement that. So that would be in the grease pencil editor namespace. And we have already this API for the drawings here. So let's put this here. Start with this. So we have the index mask that we want to return. And yeah, so we want to pass in an object. I don't think we can use a cons reference here, which would be ideal. But most of the material API still C-like hasn't been reported to more modern C++ styles. So we just have to accept that and use a mutable reference for now. So this would be the grease pencil object. And then we can pass a cons reference to the drawing. And then we have the index mask memory. There we go. Yeah, looks good. All right, let's try and see if we can implement that. This would go into the utils. Yeah, again, this is where we have the other API right now. Cool. Maybe for a good measure, we'll just assert that the object is actually of the right type. So this is OB grease pencil. All right, what's the first step? So in the end, we want to basically check all the material indices and if they're locked or not. So I think a good first step might be to build like a vector set of material indices. I need to include that here. That would be a vector set of h. So this would be the locked material indices. So we can, I guess, just loop over all of the material slots. Something like mat i, use an index range. So this is on the object that should be in sync with the object data materials, I think. And for each material, we want to actually retrieve the material. So I think that's in material.h. Something like object material. Yeah, this is what we want. Because I think this will both look at the object materials, but also use the object data in some condition. So this is the API we should use, I believe. Let's go back, there we are. So we have the material. Material is the material we want to get. So we have to pass in the, right, should include material. So pass in the cp object, and we want to pass in mat i here. And then if we get a material, so if material is not equal to null pointer, and so now we need to check for the material settings for cp. So this is stored in material, right, to add the DNA for that. Material grease pencil style. So this is the grease pencil information. So if that's also not equal to null pointer, and then we can check if the, because it's in the flag, right, yes. And there we have the locked flag. So we have to check if the flag, and then we do the classic material locked. So we want to end it with that, and we want to check if that thing is not equal to zero. So if the flag is set, then we know that this material is, one of the materials that's locked. So we should put that index here into our locked materials. So we can do an add, I guess we can use add new here even. I believe that's the, adds a new, yeah. But since we're iterating over a range here, we know that every one of these is going to be a new one. So we can use add new here, and be a bit more efficient, cool. So now we should have all of the locked materials. So let's maybe first start by figuring out which are the unlocked grease pencil strokes. So really what we want to do is we want to get to the attributes. So let's start by going to get the curves. Yeah, I think this should be const, const curves, and that's the drawing, and we get the strokes. Maybe I should call it strokes, but we've been sort of inconsistent with that a bit. They are curves in the end, so I'm going to be consistent with the rest of the code for now. And then we have a const attribute reader. Let's see, where can I copy some code for that? In the curves selection, yes, cool. So this is the function that we use to retrieve the selected curves. But we want to get the attribute accessor, which is also in the kernel. I should have remembered that. Right, and I guess we need to include... That's a bit strange, that doesn't know about this stuff. But we can of course include that. So this would be curves.hh. And then we want to access the material in this use. So that would be a virtual array of type int material says. And we're going to go to attributes and look up our default material index. Is I think the name. Double check that. This pencil convert legacy. This is usually what I check to see how we rename things from old to new. So in this case we have a mutable attribute accessor. But we don't really want to create this material index attribute. We just want to retrieve it and if it's not there we just have to use a default value. But it's on the domain curve. That is true. Now we have the default value so let's just use negative one. It should be good. I think we just dereferenced that and that should work with the API. Yeah, cool. Because it gets an attribute reader but that can be converted to a virtual array. Using some operator overload. Okay, so we have the material indices. And then what we're basically going to do is let's create an index mask memory thingy thing. And then do a const index mask. And I think we're just going to use from predicate. So this would be the unlocked materials. And that would be index mask dot from predicate. So the universe in this case is the curves range. Let's actually get that. Index range, curves range. That's just curves dot curves range. Cool. So that's our universe. The grain size. Let's just use something big. And get the memory and finally predicate. Which in this case I think it's just going to be the index. So this is a lambda that builds the actual index mask. So I think what we get here is like constant index. Which in our case would be the curve index. And what we want to do here is just return. Let's do the clean way and do const and material index. Is our material indices the curve index. And then what we return is we want to look up if this index here is in this vector set. So we do a contains material index. And if it's not in there, then we return true. Because that means that it's unlocked. Cool. And then let's do another index mask. And let's get these selected strokes. Or just selection I think works as well. In this case we can just reuse the function that we have in the curves geometry. So that's in ed curves. And this is the retrieve selected curves. There we go. And I think this has one. Yeah, we just pass in the curves geometry. So we pass in the curves here and we pass in the memory. And that gives us an index mask of what curves are selected within the whole curves geometry. And once we have that, we basically want to combine them. So what we want to do, we might have multiple ways of retrieving editable strokes. But I think for now what I'm going to do to get our example working. Remember we have this operator here. Honest. Something will figure that out. We want to get the strokes that are selected and have an unlocked material. So yeah, we basically want to do a sort of ant operation on these two index masks. Which I don't think we have. From union. We want to do an intersection. So no, this is not what we want to do. We don't want to union them. Because we want to figure out where they're both true. So I think we're just going to use a from predicate here. This can be rewritten in a better way in the future. We basically want to reuse this API here. Like that. And then we want to say, if unlocked materials at curve i Wait, no, no, sorry. Dot contains curve i. And this is why it's a bit expensive to do this. But we'll do this for now and deal with it in the future. And selection contains curve i. So now we're doing the, if both of the index masks contain that index Then we know that this is an editable curve. And we build the index mask from that and return it. Cool. So yeah, that looks good. Let's see if we can get our thing working here. Tree, editable, strokes, memory. Okay. It's not like the fact that I'm making this const here, maybe. No, okay. I'm not sure what's going on, but we can figure it out. Let's see what the... Oh, I need to pass that by reference. I think I do. Yeah, let's double check how that's used in the curve selection. Yeah, it's passed by reference. That makes sense. I don't want to copy the memory. I want to reuse the one that I declared in this place here. Cool. So now it works. And yeah, we check if we're empty, then return. So actually we could put this guy here. Just check if that's there first. Then it curves. And then actually look up or add the thing. So let's see if that works. Parameter. Oh, because I don't want to create this memory here. I actually want to use the memory I'm getting from outside. It looks like we're linking. Perfect. So now we've got to debug the code. Let's see if it works. Obviously, this is just changing one of the operators. Basically all of the other operators will have to somehow use this API or a huge API that does something similar. Like maybe we want to retrieve the editable points instead of the strokes. But let's see how we're doing with this operator. So that material is locked. We have the white one selected. So let's do our assign material. And it didn't work. So we will have to do some debugging. Let's first see what happens with our locked material indices. Let's just have a print or something. That would be awesome. Probably at the very bottom. Private calculation. I guess I can just try. Let's see out the end line there. It doesn't like it. In that case we just doubt the index here. Maybe something like material. Just for debugging purposes here. Let's print that on new lines. Because obviously if this is empty, then we're just going to change everything that's selected. Unlocked material also. Seems good. It's 30123. Right. This is a classic material slot indexing problem. The material slots are 1 index-based and not 0 index-based. So we have to pass this plus 1 here. Because obviously the index should have been 2 instead of 3. I would also explain why we didn't see the red ones not changing. Because it would have picked the one material below that instead of the correct one. This is a classic material slot thing. Sign material. Here we go. Now it works. Cool. So I just had the off-by-one error here with getting the material. If we look in here, you can see that it subtracts 1 here. Because that's the actual index. Because they're 1-based. Then it uses that to index into the material slots. Material arrays. So yeah. But that's it. So we pretty much now have a function here that can give us the... Let's remove the print here. That can give us the editable strokes. And we can of course expand this in the future. If we have something else that means you can't edit a stroke for some reason. We could add that to this function. And hopefully every operator would use that. To get the editable strokes. But yeah cool. That only took like half an hour. Which is awesome. And I think we can stop the video here. Let me know if you enjoyed that. And see you in the next video maybe.


This study found that helicobacter pylori, HP, infection is associated with lower body mass index, BMI, in hematialysis, HD, patients. After six months of successful treatment, the BMI of these patients improved significantly. Additionally, the study showed that eradicating HP had an effect on other clinical parameters such as serum albumin levels, cholesterol levels, blood urea nitrogen levels, and calcium levels. This article was authored by Majgen Jalazzata, Mohamed Hassan D'Adiani, and Nuradin Musa Vinisab.


Welcome, everybody. We're here to have a chat about working with security groups. My name is Jacob Walsik. I work for Rackspace. I'm a principal solution architect with our private cloud group. So what we're going to talk about is applicable to most private clouds, not today, to the Rackspace public cloud. But everything we're going to talk about will be true of just about any OpenStack cloud that you're going to consume that is using Neutron for networking. Quick introduction. I've been with Rackspace since 2007. I've been working with OpenStack since 2010. I started playing with the early Diablo releases and then have stuck with that ever since. I'm not sure how many of you have worked with security groups with Nova Network versus Neutron. But one thing to be clear on, we are just talking about Neutron today. Some of the functionality is different. We're also not talking about firewall as a service. So if you were here hoping to learn about firewall as a service that is not going to be covered today, I did not see another session on firewall as a service. There is a Neutron networking hands-on at 4.30 tomorrow that may have some content. I was unable to reach the authors and find out. And we also won't be looking at any live demos. There's going to be plenty of lovely screenshots of command line input and output. There's not really much to demo when you're creating, destroying, modifying security groups. So I just stuck with the screenshots. I'll upload this to SlideShare after the presentation. And of course, they record these. And they'll be available within a couple of days. All of the commands that you see have been verified to work on IceHouse. So first, what are security groups? This is the definition from the docs.openstack.org site. Security groups and specifically security group rules are what allow us to define access into or out of instances. And it's the security group rules that actually do the work. I can create a security group. I can call it whatever. I can assign that security group to VMs. But it's just going to use the default behavior that all security groups have. And the default is no traffic in, all traffic out. It's not until I start defining rules, which will be some combination of a protocol, a series of ports, ingress or egress, a IP range, or even a different security group for my source or target. That's when I start being able to actually do filtering or to allow access into my VMs. The majority of the time we're going to spend in here today is going to be in this section here on creating security groups. When I set down to really dig into the difference in how security groups behave with Nova Network and Neutron, I discovered that there's not a whole lot of interesting stuff that you do other than creating the groups themselves. Once they're created, you start assigning them to instances. But that piece is pretty trivial and is more or less stayed the same as we've moved from Nova Network to Neutron. So security groups themselves are implemented, assuming you're using the KVM hypervisor with IP tables rules on the hypervisor. You'll see these security group rules show up as individual chains for every single VM. Every VM on that hypervisor will have three chains. If you look at the names of the chains that are on the screen right now, the top one starts with the letter I. This is where the ingress rules go. The bottom one starts with the letter O. This is where the outbound or egress rules go. There is a third chain that you see referenced there. It starts with an S. That is where the MAC address is added for any outgoing packets so that they have the appropriate source. When we go to create security groups, there are a couple of different tools we can use. The Nova commands for creating security groups still work. They just pass that functionality on through to Neutron. The Neutron tool also works and exposes the full complement of functionality that's available once you start working with Neutron. One of the biggest differences is that if you want to create egress security groups, you need to use the Neutron tool to do it. It allows you to specify whether it's an incoming rule or an outgoing rule. They're with the direction flag. If you have automation that already uses the Nova commands, that's great. Like I said, it'll keep working. But if you want to start using some of the different functionality, you will have to move at some point in time and start using Neutron to create the security groups. So when you create security groups, Nova will not enforce a unique name or Neutron will not enforce a unique name on the security group. I would recommend not creating a bunch of security groups with the same name. Anytime you create a tenant, there's going to be a security group called default. That security group will allow traffic between all the VMs that are part of that tenant that are a member of the security group default. It won't allow any incoming traffic, and it will allow all outgoing traffic. If you want to allow any additional traffic into those VMs, you have to explicitly allow it through a security group rule. The UU IDs that are shown here are what you end up having to use if you start creating security groups that have conflicting names. So if you like playing with your UU IDs, and I'm sure everyone does, then by all means call all of your security groups Bob. If not, then give them something more meaningful. When you start adding rules to security groups, you're generally using either a single port, as we see here, with 80 and 443, or you're going to be using a range. So if you have a service that uses a range of 10 ports, you can specify the first number will be the beginning of the range, the second number is the end of the range, and you can get away with just creating one rule. You're also going to specify the cider for where the traffic can come from. So here we have two rules that are opening up ports 80 and 443 globally for all incoming traffic. That could very easily be a different networking range within our cloud, a different networking range for another application environment in our data center, or it could be some public range that we're allowing in because there's routes that get through into this piece of our private cloud. Here is the creation of a security group using Neutron. On this slide, we've got the Nova Network commands. Here we've got the Neutron command. When you're creating them, it's obviously very different. I've had to truncate some of the output here because you get a big chunk of JSON back when you're creating them via the Neutron tool. And then here is adding that same rule in. Again, we're going to start getting a big chunk of UUIDs. If you've been working with the Neutron utilities, you're going to start to become accustomed to this. When we start looking at applying security groups with Neutron, you'll notice that we start applying to ports that are going to be a unique ID. We're not applying them to individual VMs anymore. When you create a security group, rather than specifying a source-sider range, you can also specify another security group. This allows us to start creating tiered applications. As we look through this presentation, you'll notice that there is a security group for proxy servers and a security group for application servers. And the application servers only accept incoming traffic from the proxy servers. If you are accustomed to deploying three-tier applications, setting up a DMZ, this is the exact same model that you can bring into your security groups. When you boot an instance up, you have the ability to specify a list of security groups that you would like for it to be a member of. If you're using the Nova command line tool, it's just dash, dash security groups, and then a common delineated list. Once an instance is up and running, you can modify which security groups are attached to it. The security groups you see here are whatever. I've added a security group to the proxy01 instance. I've added the Linux servers security group. And the command here is shown, both the Nova command, which, as I mentioned before, is what most of you are probably used to working with, and the Neutron command. Once again, the Neutron command, we get a lovely handful of UUIDs. Neutron won't let you delete a security group that has any instances attached to it.  You don't want to allow PING, whatever the case may be.  It will come back and tell you no. So you'll have to figure out which instances are still configured to consume that security group. And you'll have to go through and either remove that security group or change the rules within the group itself. So through the process of creating this presentation, as I mentioned, I learned quite a bit about what to do with the security groups themselves and how they apply. One thing to keep in mind if you are using Nova Network is there is a flag that's in your NovaConf called allowSameNetTraffic that has a substantial impact on the behavior of security groups. If you're using Nova Network and you have multiple tenants that are consuming the same network and you have allowSameNetTraffic turned on, then it will allow traffic between VMs across tenants. This behavior does not appear to apply in Neutron. The docs today don't reflect that. I could not find a way to have that flag set to true or false and have it influence the output of the security rules that were created. So that is something to be aware of. The documented behavior is that if it's set to true and you have the same network used by multiple tenants, then the traffic should be allowed to pass through. And that is definitely not the behavior that I saw in practice. Do we have questions? Yes. Enabling IP tables logging? There's not a way to do it that I'm aware of. So the logging that you would set for catching all of the bad behavior that comes in, say, hey, I want to see everybody that tried to hit 22 on this that wasn't explicitly allowed in, I'm not aware of a way to do it with the native security group tools that are available through Nova or Neutron. I mean, the solution that I would propose to that would be filter that at the edge and do your logging there. But that doesn't help if you have multiple tenants and you're worried about your tenants misbehaving when they're communicating with each other or about an application that might go rogue within your cloud. I'm sorry, I can't hear you. You know, VMs communicating on the same tenant. You know, if you have rules in place to restrict that with security groups, there's no visibility, right? Yeah, so the default security group, which will be applied to every new VM that you create within a tenant, allows all of the traffic from those VMs to communicate. So you have to explicitly say, I don't want the default security group. I just want this one in my proxy servers security group. Right. In which case, only the, whatever, only the incoming 84, 43 should be allowed. But I'm not aware of a way to log like an incoming attempt to connect to 22 on that VM. I'd assume you have to do it through IP table somehow. You would have to do it through IP tables. It can get pretty dicey when you start injecting security group rules or injecting your own IP tables rules in conjunction with security groups. All of your security groups get managed by, you know, all those IP tables rules are getting managed automatically. And so when you have a, when I say I've got my application servers security group and I'm allowing incoming traffic for my proxy servers security group, every time I add a new VM to the proxy servers security group, every VM that's in the application servers security group gets its current IP tables rules updated to include the additional source address. So unless you had a very static configuration, those rules are going to get stomped on if you try and start putting them on the interfaces that are getting managed by, by Neutron. And how do you see the kind of the evolution here with firewall as a service then the evolution of security groups? Do they go away? Do they work with each other? Security groups stick around. Firewall as a service is intended to provide protection at the edge of the tenant. So if I have multiple tenants and I've got a set of developers in each tenant and maybe they're each running a piece of my application they can decide what traffic they're going to accept from the other bits of my application. There's been talk though about, you know, firewall as a service moving down to like layer two but I don't think anything's there yet. I definitely don't think it's there yet. And with the problems that you already have, I mentioned that you can do security groups can use another security group as their source address. So when you do that, you start the behavior of every time I add a new security group to proxy servers, all my app servers get their security group rules updated. So if I've got 500 proxy servers and 20 or 200 or whatever application servers, I start this cascading effect. Every time I add another one to either group, all those rules have to change. Which kind of comes down to the fact it's not super, I guess it's scalable but it's not in the long term a great solution. Yeah, it's scalable but it's no more scalable than IP tables is natively. I mean IP tables is what IP tables is. That's the tool that was used to implement this. I can't think of a better one that they could throw in there tomorrow. So that's using security groups in a limited basis because of the default behaviors is easier. By default, nothing gets in. So I'm only setting up one IP tables rule that says I allow SSH or I allow HTTP or I allow whatever my SQL, whatever the service is that VM is running or that family of VMs are running. And support is still just limited to KVM, right? It varies based on the hypervisors. If you go out and look at the hypervisor compatibility matrix that's on openstack.org, there are several other hypervisors that list it as being a thing. I have no idea how they're implemented. I know some of the older VMware stuff required a Linux VM running on every ESX host. I don't think that it would be practical to funnel all the traffic for that hypervisor through that one VM. So I'm not sure how they go about implementing it with something other than KVM. Yeah, I mean, I thought it was only KVM still, but maybe. I mean, like what you're saying you can do, but it doesn't scale at all. Yeah, the funneling all traffic through one VM creates the same problem that we have with L3 and Neutron where we're now funneling all traffic through one physical host. And it's bad enough when it's a full blown box with 10 gig NICs. Thank you. Yes. So the question is, is there, am I aware of any plans to expand the security group functionality to include more like IDS or application firewall style functionality? With the way that they're implemented now, you couldn't filter for anything that IP tables couldn't filter for. It's like you couldn't do any sort of layer seven stuff where you're watching for a SQL injection or a WordPress vulnerability or anything like that. That would require some alternate implementation of security groups that use the technology that was able to do that sort of inspection. Either some sort of proxy service or integration with an appliance like what, alert logic cells, and then like that. If you have that type of service, that's something that's going to have to be implemented elsewhere. It's not something that security groups is going to do for you. So you'd either have to do it inside of each of your VMs or you'd have to do it externally with some sort of security appliance, the common way that you would today. So inside of your VM, instead of accepting direct HTTP requests, you could have some rules with something like varnish that rejects any traffic that matches a certain pattern. So if you know that there's a common, if you're running WordPress and you know that there's this new SQL injection that hasn't been patched yet, you could match that traffic in a proxy service and just return a 500 and say, nope, go away, instead of passing it through to your application server. Yes, then you would have to use some sort of tool to manage all those proxy servers in their configuration. So that's when you would be getting into what kind of automation are you using to deploy your application itself versus leveraging the infrastructure to provide security. I'm not familiar with that specific phrase, but there are various proxies available for most of the common services that allow you to do that deep inspection of requests for that service. And so you could use that to say, you know what, I'm going to proxy that off to DevNull, essentially, whether that's an HTTP service and you just return an error code, or it's a SQL connection string, and you just drop it. If you used an admin user to modify the default security group and then didn't give the tenant access to have any additional security groups, with their quota, I believe that would work. I'm not 100% sure. Yeah, I think this is whatever. There's not a lot of really good role-based access control there. I mean, if you have a user within that tenant that is an admin for that tenant, they're going to be able to modify that rule. So conclusion. Security groups are the best way to provide security within a OpenStack cloud between the VMs that are within a tenant and to manage the incoming traffic that may be coming into that tenant from outside your cloud. You can manage some of this with Edge devices. You can manage some of it by how you control your network. As you saw from some of the questions here, however, there is always the concern about what happens when the bad traffic is coming from inside the cloud. So following the rule of having a policy that allows the least amount of necessary traffic into your VMs is always recommended. That's all I have today. If anybody has any questions, please feel free to step up to one of the microphones or I'll be outside here after we wrap up.


Dave is a service-connected veteran who served in both the U.S. Army and the U.S. Coast Guard. He enlisted in the Army in 1976 and served as a radar repair technician. Upon his completion of the term with the Army, Mr. Riley joined the U.S. Coast Guard in 1983 and served as a helicopter rescue swimmer. While on active duty with the Coast Guard, Dave contracted a debilitating disease which resulted in the loss of four limbs and a subsequent medical retirement. Dave continued his education, earning a bachelor or master's degree in computer and information science from the University of South Alabama. Mr. Riley joined the DAV in 1997 and he is a life member of Sheehan Paik Chapter 7 in Mobile, Alabama. In 2010, Dave Riley was selected as a DAV Outstanding Disabled Veteran of the Year. He was the first Coast Guardsman to earn this award. Commander Riley was active in chapter and department activities and both leadership and service activities. He has held a succession of chapter and department offices, culminating in his election as Department of Alabama Commander. Ladies and gentlemen, may I ask you to welcome our national commander, Dave Riley. Thank you, ladies and gentlemen, for that warm welcome.  I'm joined this morning with a very special guest. I'm talking about a renowned medical professional who has a dedicated career of serving us all. A son of a soldier born at an Army hospital, this individual served veterans the past year and a half as a VA's Undersecretary of Health during an unmatched time of transition and growth within the department. I'm, of course, talking about Dr. David Shulkin, who just a few weeks ago was unanimously confirmed as our 9th Secretary of Veterans Affairs. Ladies and gentlemen, please put your hands or hooks together for him. Dr. Shulkin, as you can hear from the applause, we are honored to have you here at our annual Midwinter Conference. We're looking forward to hearing from you regarding the improvements to Health Department, led as Undersecretary of Health, how you will continue to build upon these past successes as Secretary. DAV believes the intrinsic value of VA is irreplaceable. They specialize in veterans and have been a long leader in many forms of treatment, therapy, and research unique to our community. During testimony to the Senate Committee on Veteran Affairs earlier this month, Dr. Shulkin said, VA is a unique national resource that is worth saving, and I'm committed to doing just that. Dr. Shulkin, for the past year and a half, has illustrated a commitment to working with the DAV for solutions that were best for veterans. I thank Dr. Shulkin for standing up for the men and women who served during his tender as Undersecretary for Health. As National Commander of DAV and on behalf of our 1.3 million members, I look forward to working with this Secretary. I've had a chance to meet with him a number of times, and he's a warm human being. He really genuinely cares about veterans, and I'm excited for this continuing year. As a disabled veteran and user of VA health care, I look forward to experience the major transformation and reforms underway at the VA firsthand. At DAV, we talk a lot about keeping the promise to our nation's veterans. America has a contract with those who served, and the Department of Veteran Affairs holds a significant piece of that contract. But a contract is a two-way agreement, and we must uphold our end as well. For our part, we will continue to provide you with the feedback and honest insight we receive from our members. There's much to be learned about the operations of the VA system from the men and women right here in this room. And I'm confident VA leaders, including Secretary Shulkin, are listening. This week and throughout the year, we will be addressing some very critical topics, including health care and appeals reform, improving services for women veterans, and support for all our caregivers. But at the very front of the line is safeguarding and improving the VA so that we can ensure all veterans today and tomorrow have a system accountable to them for their injuries and illnesses sustained in service to this nation. That's why we're using DAV's Operation Keep the Promise as a platform to educate veterans, Congress, and the new administration on a smart approach to reforming the VA. For several years, there has been a vigorous national debate about how to best provide timely, high-quality, comprehensive, and veteran-focused health care to our nation's heroes. We know that some veterans have difficulty accessing VA medical care, so private sector options should play a role when it makes sense for meeting the unique veterans' needs. Choice should be a part of the solution to fixing VA health care, but it has to fit into the big picture to ensure better health outcomes for veterans. That's why DAV and other VSOs have proposed the creation of an integrated network to combine the strength of the VA health care system with the best of community providers so the veterans have real choices. Now, VA leaders in Congress and the congressionally mandated Independent Commission on Care have all reached the same conclusion. As you fill the halls of Congress on Tuesday or meet with your representatives and senators throughout the week, your message must be clear. We are veterans. We take care of veterans.  No matter the ear or branch we served in, man or woman, young or old, we have sacrificed for this nation. We have upheld our end of the contract and now Congress has to ensure they stay true to it as well. Veterans' issues should never be partisan and we expect our elected officials to work together in the best interest of all those who served. Now I want to take a moment to recognize some important people in the audience today. Our National Service Officers and Transition Service Officers provide their every day face-to-face with veterans, making an incredible impact on the men and women who served, as well as their families. So too are DAV's Department and Chapter Service Officers. They stand ready to ensure every veteran has access to free professional representation. I would like to our National Service Officers, Transition Service Officers, and Department and Chapter Service Officers with us today to stand and be recognized. The men and women accredited or certified by DAV as Service Officers, over 4,200 strong and the face of DAV, are often the first impression a veteran has of our organization. Thank you all for your dedication and for your fellow veterans. Service work is truly the bread and butter of DAV. It's what we do best and what we are known for. But between DAV and the auxiliary, we are also reaching more and more veterans through volunteers serving in VA facilities across the country. Donating approximately 100,000 hours per year, we have also dedicated DAV volunteer drivers who provide around 700,000 rides annually to veterans, ensuring they have access to care. Since beginning in 1987, our drivers have totaled more than 660 million miles and donated more than 37 million hours of their time to this program. Nearly 18 million veterans have benefited from the DAV Transportation Network. While these are impressive numbers, there's still an unmet need. All the fundraising we do can't replace the presence of our volunteer forces. Volunteerism across the country, as you may know, is in decline. It's a trend we look to reverse. Many services injured and ill veterans depend on count on the spirit of hard-working volunteers. That's why this Wednesday we are kicking off Forward March, a campaign to encourage all those who have received DAV's assistance and all our supporters to pay it forward by volunteering one hour of their time to help local veterans. This campaign will provide ways they and all other patriotic Americans can lend their time in support of our nation's finance. DAV created the Local Veterans Assistance Program, or LVAP, to enable volunteers to perform service work that meets the unique needs of veterans in their communities. Forward March will encourage people to support veterans through the program and promote volunteerism and participation in the program through social media like Facebook and Twitter. And don't worry, there is a social network workshop tomorrow afternoon, so if you don't already know how to harness this powerful communications tool, you will after Monday's session at 4.30 in this room. There are so many of you already out there giving back to your fellow veterans. I think that kind of dedication from all volunteers, as well as our hospital service coordinators, deserves a little recognition. So for those of you with us today, please stand for a much-deserved round of applause. I'm always inspired by the giving nature of volunteers, but these men and women are truly standout group. Thank you all. Please consider joining these patriots next month when we give back to our fellow veterans and Forward March. Another group of people I would also like to take a moment to recognize are the professional staff in both Cold Spring and Washington. They are constantly working to improve the programs and services we offer and to ensure DAV is doing everything possible to better serve veterans. Mark Burgess, Barry Jezanowski and Gary Augustine, you have assembled a phenomenal team of professionals within the Veterans Advocacy Arena and the work you do is second to none. As veterans and members, we sincerely appreciate all the work these teams do in order to further the DAV mission. Thank you. I would be remiss if I didn't also thank our counterparts in the auxiliary. DAV has no better friend or closer ally than the DAV auxiliary. Under the capable leadership of auxiliary national commander Fran Costa and national agitant Pat Kemper, your support is invaluable and we are blessed to have such a devoted partner. I especially want to thank Fran for her dedication and supporting caregivers during her term as leader of the auxiliary. For nearly a century, DAV has stood as the champion of veterans' causes. I can assure you this year and in the years ahead, we will face many new trials including challenges to our compensation and health care programs. Your attention to the issues, your support in our advocacy campaigns and your voices lending depth to our message have never been more important than they are now. We need you to be DAV's ambassadors. Take what you learn and experience this week home with you. Spread the message and invite your fellow veterans to join by our side. It's through our ranks nationwide that we move closer to achieving our goals. Never forget the men and women we're fighting for, the veterans here in this room, the veterans in long-term care and nursing facilities, the veterans coming home each and every day. They make difficult transitions back to civilian life and the service members currently oversee and harm's way. Let these men and women guide your daily efforts. The mission of service is never complete and we owe our fellow engineer Nell veterans the best DAV has to offer.  May God bless the DAV, may God continue to bless the United States of America and the men and women who continue to stand watch to defend her. Thank you and keep up the good work.